【android】五種控制Android應用的許可權的方法
轉自:http://www.cnbeta.com/articles/181913.htm
1 為什麼Android總是事無鉅細地告訴你應用索取的每一項許可權?
相比Apple,Microsoft嚴格控制生態系統(從蘋果給開發者的"App Store Guideline"可見一斑),只允許通過官方應用商店安裝應用,並對每份上傳進行仔細地審查而言,Android的開放就意味著,Google需要向用戶提供一系列用於為自己負責的流程、工具。所以在安裝應用前,Android總是要事無鉅細地告訴你,應用肯需要控制什麼許可權。
同樣,開發者也製作了一系列易用的工具,用以鑑別可疑的應用程式,或是控制權限。
圖1 Android 官方市場會強制提醒用
Andoird哪裡開放了?
在Android中,使用者能自由從本地安裝應用,自由地對SD卡進行操作,自由選擇應用市場。
如果願意放棄保修,使用者還能輕易地實行root,解鎖基帶(baseband)。只有一些產品會嚴密地鎖定bootloader(如摩托羅拉)。
最重要的是,因為ASOP(Android原始碼開放計劃)的存在,絕大部分的Android程式碼都是開源的,開發者可以由此對Android系統進行深入的修改,甚至可以自行編寫一個符合Android規範的系統例項(如Cyanogen Mod)。正是因為ASOP,這篇文章才可能介紹多達5種原理不同的許可權控制方法。
圖2 Android開源計劃的標誌
開放的風險
不考慮Symbian,Windows Phone 6.5(及以下)平臺,那麼幾乎所有的智慧手機病毒都是Android平臺的,甚至官方Android Market也鬧過幾次烏龍。在國內水貨橫行的市場,情況更是火上澆油,不法業者可以在手機的ROM,甚至是bootloader中做好手腳,讓使用者有病無法醫。
在Android中,使用者可以允許系統安裝來自"未知源"(也就是非Google官方的,或手機預置市場的)應用程式。於是,移動平臺最重要的門神------數字簽名就被繞過了。
圖3 Android 允許未知安裝未知來源的應用程
出於Android的開放性,也有不允許"未知源"的反例:亞馬遜的Kindle Fire平板使用了深度定製的Android,它只允許安裝來自亞馬遜官方商店的應用程式。
圖4 亞馬遜的 Kindle Fire 僅允許通過自帶的市場安裝應用
2 Android有哪些"許可權"
首先需要明確一下Android中的種種"許可權"。Android是在Linux核心上建立一個硬體抽象層(Android HAL),通過Dalvik以及各種庫來執行android應用的。在手機啟動時,首先需要由Bootloader(HTC手機上稱作Hboot)引導Linux及手機上各個硬體裝置的驅動程式,之後才啟動Android系統。所以其實我們會涉及到四種不同涵義的許可權:
Android許可權(Permission)
這指Android中的一系列"Android.Permission.*"物件,是本文的中心內容。
Google在Android框架內把各種物件(包括裝置上的各類資料,感測器,撥打電話,傳送資訊,控制別的應用程式等)的訪問許可權進行了詳細的劃分,列出了約一百條"Android.Permission"。應用程式在執行前必須向Android系統宣告它將會用到的許可權,否則Android將會拒絕該應用程式訪問通過該"Permission"許可的內容。
比方說,搜狗輸入法提供了一個智慧通訊錄的功能,使用者可以在輸入聯絡人拼音的前幾個字元,或首字母,輸入法就能自動呈現相關聯絡人的名字。為了實現這個功能,輸入法必須宣告它需要讀取手機中聯絡人的能力,也就是在相關程式碼中加上宣告"android.permission.READ_CONTACTS"物件。
圖5 搜狗輸入法的智慧聯絡人功能
原生Android只提供了對"一刀切"式的管理,要麼同意使用,否則就根本就不安裝應用程式。當用戶遇到希望使用程式的同時,又想禁止部分Permission的場合,他就無路可走。
於是,不少開發者就搗鼓出了"第三條道路";可惜的是,沒有一種方法能同時做到既不需要將手機韌體Root,又完全不涉及對原始應用程式進行反向工程的方法。
Root
Root指獲得Android所在的Linux系統的Root(根)許可權,有了根許可權,你才能對Linux做出任意的修改。iOS中的越獄(Jailbreak) 相當於獲得iOS系統的Root許可權(iOS是一種類Unix系統,和Linux都使用Root的概念)。在已Root的裝置中,通常都是使用一個叫"Superuser"(簡稱SU)的應用程式來向許可的程式授以Root許可權。
Bootloader的解鎖(Unlock)
利用數字簽名,Bootloader可以限定只有正確簽名的系統可以被引導。在修改韌體以獲得Root以前,解鎖Bootloader通常是必須的。安裝第三方修改、編譯的韌體也需要解鎖Bootloader。
基帶(Radio)解鎖
在Android系統中,基帶是上層軟體與手機中無線裝置(手機網路,Wi-Fi,藍芽等)的驅動程式之間的中介。國外的網路運營商很喜歡鎖定基帶,從而保證使用者只能使用運營商自己指定的sim卡。在我國,鎖定基帶是非法的,手機制造商、網路運營商也不可以通過鎖定基帶的方法對待違約客戶。iOS的"解鎖"就是解鎖iOS中的基帶軟體。
為什麼要控制Android許可權
魚和熊掌不可兼得,Android的世界有很多自由,壞人也能自由地做壞事。它的生態系統很強調自主:使用者可以自主地減小風險,僅使用官方市場的應用程式,也可以自主地解除安全限制,從而獲得更多自由。因此,在遇到壞事的時候,使用者也不得不自主一下:
1, 抵制不道德,乃至非法行為
幾乎所有的Android安全軟體都能對來電、資訊進行控制,以減少騷擾。
另一方面,很多應用都會要求它們實際功能以外的許可權,表現在非(主動)告知地蒐集裝置序列號,位置資訊,誘使使用者預設地上傳聯絡人列表等方面。
更壞一點的應用程式,則會踏入犯罪的範疇,比如能偷偷發出扣費資訊,或是作為黑客的偷窺工具。
2, 減少惡意軟體的損害
惡意軟體即便潛伏成功,也難以獲得許可權,從而減少損失。
3, 使用者有權自主地在抑制應用程式的部分許可權時,繼續使用該應用程式,而只承擔由於自行設定不當而帶來的後果。
使用者擁有裝置的所有權,因此有權自主控制裝置上的內容、感測器等物件的訪問;同時有權(不)執行,(不)編譯裝置上的應用程式。
大多數應用程式在執行時,並未達成主動告知的義務,是失誤;然而即使主動告知,使用者還是可以不理會。
為什麼Android官方市場的強制提醒許可權的行為不屬於主動告知:
通過Android官方市場,"打包安裝器"安裝應用程式時,所顯示的"許可權"僅是在安裝包內AndroidManifest.xml宣告的值,而非應用程式實際上會呼叫的內容。該值僅用來表明Android系統能嚮應用授予的最大可能的許可權
(應用需要使用的許可權都必須在AndroidManifest.xml中宣告,所以應用使用的許可權是較容易檢查)
即便一個"Hello World"式的應用程式,也可以在AndroidManifest.xml中宣告所有可能的Android Permission。
這就是說,在AndroidManifest.xml中宣告的值與應用程式實際呼叫的許可權有關聯,但不等同,且這種提示是由Android系統負責實施的強制行為。
正確的理解是:"應用程式(被迫地)讓Android系統告知使用者,它在AndroidManifest.xml中所宣告的事項。"
這意味著應用程式在使用重要許可權前,依然需要自行、主動地通知使用者相關事宜。
圖6 應用程式須要AndroidManifest.xml中宣告呼叫到的許可權
然而,即便只是讓一半的應用程式達到以上的標準,也是不可能的。應用程式需要通過收集使用者資訊,程式的錯誤日誌。從而統計使用者的喜好,改程序序。另一方面,這也是傳送精確廣告但不追溯到使用者身份資訊的方式,這一點對於免費應用而言,是極其重要的。我們之所以能知道不同型號手機的佔有率,應用軟體的流行度,是與這樣的統計不可分離的。
一旦每個應用程式都專業地主動發出提醒,不專業的使用者(大多數使用者都是不專業的)通常會將之視為如同海嘯警報一般的危機。
這麼做對誰都沒有好處------使用者方的隱私權是毋庸置疑的,然而應用程式方面的獲取資訊記錄的需求也是無可阻擋的。如果每個使用者都打算阻止,只會落得被迫接受不平等條約的下場,在溫飽以前,不會有人考慮小康的問題。
於是,現狀就變得有趣:使用者人享受著相同的服務;其中大部分使用者出於不知情/好意,默默地向開發者、廣告商提供了資訊,剩下的少數使用者則能阻斷這種勞務。而作為維持Android平臺的資訊商人Google,只確保在它的地盤裡,不會發生觸碰底線的事情。
一句話總結:
裝置是我的,不管你怎麼說,反正我說了算,但我說的話大多是不算數的。
3 許可權控制的方法
這裡開始介紹各種控制Android許可權的辦法。可惜的是,幾乎所有的手段都需要對裝置進行Root,如果不這麼做,則需要付出不小代價。
App Shield(國內常見的名字:許可權修改器)
它是一個需要付費的Android應用,其原理是修改應用程式的apk安裝包,刪除其中AndroidManifest.xml檔案內,用於宣告許可權的對應"Android.Permission.*"條目,然後再用一個公開的證書對安裝包重新簽名(需要允許"未知源"),這樣一來,應用程式就不會向系統申請原先所需的許可權。當應用執行至相應的流程時,系統將直接拒絕,從而達到使用者控制權限的目的。
對於已安裝的應用,AppShield也會按照同樣方法制作好apk安裝包,然後讓使用者先解除安裝原始的應用,再安裝調整過的應用。除了該應用數字簽名外,使用者可以隨時通過執行同樣的流程,將吊銷的許可權恢復。
圖7 AppShield
Apk檔案的結構
Android應用都是打包成以.apk副檔名結尾,實際上是zip的檔案格式。
一個合法的apk至少需要這些成分:
根目錄下的"AndroidManifest.xml"檔案,用以向Android系統宣告所需Android許可權等執行應用所需的條件。
根目錄下的classes.dex(dex指Dalvik Exceptionable),應用(application)本身的可執行檔案(Dalvik位元組碼) 。
根目錄下的res目錄,包含應用的介面設定。(如果僅是一個後臺執行的"service"物件,則不必需)
Apk根目錄下的META-INF目錄也是必須的,它用以存放應用作者的公鑰證書與應用的數字簽名。
當應用被安裝後,這個apk檔案會原封不動地移至裝置的data/app目錄下,實際執行的,則是Dalvik將其中Classes.dex進行編譯後的Classes.odex(存放在Dalvik快取中,刷機時的'cache wipe就是清除Dalvik的odex檔案快取')。
優點:
完全不需要Root,適用於所有版本的Android裝置。不會損壞系統,可以吊銷任意一項Android許可權。
問題:
1,需要重新安裝應用,該行為可能會丟失應用的配置、歷史記錄。
2,執行許可權吊銷的應用的數字簽名會被更改,無法直接更新。對於那些設計不良(沒有意料到'不宣告許可權'情況的),或有額外自校驗的應用,可能會無法執行。
3,無法用於裝置上的預裝應用,除非製造商好心地將該應用設定為"可以刪除"的狀態。
4,這個方法修改了apk包中的內容------儘管實際上AndroidManifest.xml和數字簽名並不算是應用程式的本身,但修改它們可能引發著作權的問題。
5,需要開啟"未知源"。
6,這是一個收費應用。
CyanogenMod 7.1(及以上版本)
Cyanogenmod是一款著名的第三方編寫的開源Android ROM。
CM7.1加入了控制權限的開關,官方的名稱是"Permission Revoking",任何非系統/保護應用在安裝後,可直接吊銷任意一項許可權,其效果等價於直接刪除apk包中AndroidManifest.xml的對應條目,但不會引發自校驗的問題。CM的許可權工具的作用等同於AppShield,無非是在Android自身的許可權系統中添加了一個開關。
圖8 Cyanogen Mod 7.1中的許可權吊銷(Permission Revoking)設定
優點:
免費,使用簡便,可隨時,任意地吊銷、恢復非預裝應用的任意一項許可權;不存在數字簽名的問題,因而不影響使用自校驗的應用程式。
問題:
此功能僅在Cyanogen Mod 7.1及以上版本提供,無法用於其它rom。因為是由Android系統出面吊銷許可權,其實現原理與App Shield完全相同,同樣的,應用程式會因為設計不良而出現崩潰。
Permission Denied
這是可以吊銷任意Android應用(注意,不當地吊銷系統應用的許可權可能會導致手機韌體損壞,無法啟動)的任意許可權,對許可權的修改在重啟後生效。
實現原理應該與Cyanogen Mod 7.1+完全相同,適用於任何已經Root的系統,因為一般的Android系統雖然事實上支援許可權吊銷,但沒有像Cyanogen Mod那樣放置介面,因此需要重啟後才能應用許可權配置。同樣也有系統出面拒絕許可權而導致的崩潰現象。
圖9 Permission Denied免費版吊銷應用程式許可權的場景
優點:
效果與Cyanogen Mod中的許可權吊銷效果一致,且可吊銷系統應用的許可權。同時提供了免費與收費版本,免費版並沒有基本功能的缺失。適用於所有版本號不低於1.6的Android裝置。
問題:
調整後的許可權需要重啟才能生效。設計不良的應用會崩潰。不恰當的許可權修改會損壞系統,導致無法開機。
PDroid
PDroid實際上是一個Android核心補丁加上一個用於管理的外部應用。補丁需要在Recover環境中刷入系統,也可以由開發者自行移植入系統。該軟體在Android ASOP 2.3.4程式碼基礎上開發,僅適用於沒有改動核心的Android 2.3系統,目前還未支援Android 4。
圖10 PDroid的介面
為了避免Cyanogen Mod 7.1+許可權吊銷(Permission revoking)導致的崩潰問題,以及後臺服務(如LBE,QQ手機管家等,PDroid的作者認為通過後臺服務攔截許可權並不是好辦法),PDroid並不阻止應用程式宣告許可權,但會在其實際索取相關資訊時,予以阻止。通俗地說,就是簽署協議但不執行。在PDroid的使用者介面,使用者能隨時精確地控制涉及隱私的各項許可權。對於某些內容,除了阻止外,使用者還可以偽造一個隨機或指定的資料。
可控制的內容包括:
IMEI(可偽造)
IMSI(可偽造)
SIM卡序列號(可偽造)
手機號碼(可偽造)
來,去電號碼
SIM卡資訊
當前蜂窩網路資訊
(以上七者均來自Android.Permission.READ_PHONE_STATE)
GPS定位資訊 (可偽造,來自Android.Permission.FINE_LOCATION)
基站定位 (可偽造,來自Android.Permission.COARSE_LOCATION)
系統自帶瀏覽器的歷史,書籤(Android.Permission.BOOKMARKS)
聯絡人 (android.permission.READ_CONTACTS)
通話記錄 (android.permission.READ_CONTACTS)
系統日誌 (android.permission.READ_LOGS)
當前賬戶列表 (android.permission.GET_ACCOUNTS)
當前賬戶的授權碼 (android.permission.USE_CREDENTIALS)
簡訊,彩信 (可能與這5個許可權有關)
android.permission.READ_SMS
android.permission.RECEIVE_SMS
android.permission.SEND_SMS
android.permission.WRITE_SMS
android.permission.RECEIVE_MMS
日曆 android.permission.READ_CALENDAR
PDroid的核心補丁並不通用,每一個Rom都需要特定的補丁。開發者除了提供了幾個特定機型下Cyanogen Mod,HTC Sense修改版ROM的專用補丁外,還推出了一個補丁生成工具(PDroid Patcher),使用者可以給自己的ROM生成專用的核心補丁。使用該Patcher需要安裝JDK(java Development Kit)。
優點:
PDroid避免了通過Android系統進行許可權吊銷的導致的潛在崩潰問題,也不需要後臺服務。對隱私資訊的控制是最精細的。儘管裝置必須Root,但應用本身不需要Root許可權。
問題:
安裝過程是最繁瑣,最不可靠的,容易導致ROM損壞,適用範圍也小,需要使用者有相當的技能(能安裝JDK,會刷機)才可使用;只提供對隱私有關許可權的控制,不提供網路訪問,的控制。以這些為代價,它幾乎沒有其它缺點。
LBE安全大師
實際上最常用的是以LBE為代表的通過一個Root許可權的後臺服務來攔截相關行為的工具。除了LBE外,還有QQ手機管家等應用。這裡以LBE安全大師為例介紹。
圖11 LBE安全大師
LBE是國內一個叫"LBE安全小組"開發的工具,支援Android2.0~4.0。它的核心功能是像防毒軟體一般,通過一個需要Root許可權的後臺服務,劫持所有呼叫許可權的行為,並放行使用者許可的部分(其官方宣傳為'API級別攔截')。它和PDroid一樣幾乎不會引發應用程式崩潰,它支援攔截幾個涉及使用者的關鍵許可權(LBE手機管家3.1/3.2):
讀取簡訊 (android.permission.READ_CONTACTS)
聯絡人記錄 (android.permission.READ_CONTACTS)
通話記錄 (android.permission.READ_CONTACTS)
定位 (Android.Permission.COARSE_LOCATION
Android.Permission.FINE_LOCATION)
手機識別碼 (與Android.Permission.READ_PHONE_STATE有關)
通話狀態 (與Android.Permission.READ_PHONE_STATE有關)
傳送簡訊(具體原理不明,同樣類似於禁止這五個許可權
android.permission.READ_SMS
android.permission.RECEIVE_SMS
android.permission.SEND_SMS
android.permission.WRITE_SMS
android.permission.RECEIVE_MMS)
撥打電話 (android.permission.CALL_PHONE)
通話監聽 (android.permission.PROCESS_OUTGOING_CALLS)
除此以外,LBE還可以分別控制應用在Wifi,手機網路的聯網許可權,其原理是依靠IPtables防火牆,而非通過Android的"Internet"許可權。
此外LBE手機管家還提供基於智慧內容審查的簡訊攔截、來電歸屬地顯示,以及禁用系統(保護)應用,程序管理,防毒等功能。
LBE提供兩個版本,一個叫"LBE安全大師",是一個全面的手機管家類應用,更新比較頻繁,另一個版本(LBE手機隱私衛士,LBE Security lite)僅提供許可權方面的管理。
考慮到主要市場在國內,LBE的發行策略看上去有些奇怪,它在Google的官方市場並不發行最新版。通常只能只能在LBE的官方網頁,以及國內的應用市場獲得最新版本。
優點:
使用非常簡單,功能強大而全面,風險很小,可以控制系統應用。適用範圍廣,有很多替代產品。
問題:
需要後臺服務 (儘管蠶豆網有個評測,認為它對能耗幾乎沒有影響),不能控制所有的Android許可權。
4 自啟動的控制
Android對後臺服務有著最好的支援。
在Android中可以自由地開發一種稱為'Service'的後臺執行的物件,加上沒有蘋果公司對應用程式的嚴格限制。諸如QQ掛機,即時呼叫第三方應用程式之類的形式都可以輕易實現。
為了全面支援後臺服務,也為了適應移動裝置資源緊張,不得不經常清理記憶體的問題,應用可在系統中設定觸發器,當系統發生了某個特定特定事件時(系統啟動,撥打電話,收發資訊,安裝、解除安裝應用,插上電源等,或應用程式自行定義的事件),就會觸發啟動應用程式。
AutoStarts 自啟動管理
AutoStarts是一個收費應用,通過它,使用者能瞭解系統中每一項程式會在什麼場合下被觸發執行。如果提供Root許可權,則還能禁止這樣的行為。
這裡以Google Maps應用6.2版為例。預設情況下,這款應用總是會保持後臺執行,並每小時向Google傳送一次當前使用者的位置資訊。為了阻止這樣的行為,需要聯合使用AutoStarts與任意一款程序管理應用:在AutoStarts中,阻止Google Maps的自行啟動(如圖),在每次使用完後,把Google Maps的程序殺掉。
圖12 AutoStarts可以對自啟動專案進行修改
5 其他
Root帶來的風險
有一個鑽牛角尖的說法認為,一旦對裝置進行了Root,便無安全一說,只要惡意程式一旦偷偷獲得Root級別,一切都是空談。
這種說法之所以鑽牛角尖,是因為:一方面Android中的Root許可權通常都是需要使用者通過Superuser應用進行授權的,這已經夠用,雖然不能指望Superuser無懈可擊;另一方面,控制Android許可權主要是為了讓應用程式在"灰色地帶"的行為收斂一些,它們實際顯然不是病毒等犯罪軟體。
著作權的問題 (作者不是法律方面的專家,以下言論僅供參考)
我們知道,Android中的應用程式是基於Java語言編寫的。而為了達到跨平臺的目的,Java軟體是以位元組碼(或叫中間程式碼,bytecode),而非計算機能直接執行的機器碼(Machine Code,有時也叫作Binary)的形式存在。因此執行Java軟體時,需要一個Java虛擬機器(Android系統中的Java虛擬機器就是Dalvik)負責解釋執行,有的時候,虛擬機器還會通過即時編譯(JIT)的方法將位元組碼編譯為機器碼後再執行,以提高程式的執行效率。
這就出現一個很有趣的現象:
除非另行規定,作為裝置的擁有者,使用者總是可以自行決定如何使用軟體,能自行決定程式能否訪問使用者自己的計算機(移動裝置亦然)裡面的各個內容、物件。
由此衍生出,在需要對程式碼編譯、解釋的場合,使用者也能通過對編譯器(直譯器)的干預,來影響程式碼的執行效果。在Android中,使用者還可以在Dalvik解釋、編譯的時候動手。
這是因為,著作權僅保護了軟體程式碼不受到非授權的反向工程,未授權傳播等侵犯。另一方面,對於Android上的Java,網頁中的javascript程式,賦予使用者解釋、編譯的權利是程式能執行的先決條件;同時,軟體發行者發通常也會主動提出放棄這種權利(表現為'軟體按原樣提供'、'不對使用軟體造成的後果負責'等條目)
在編譯、解釋的過程中,需要通過彙編(Assemble),連線(Link)等方法將編譯好的物件(Object)、方法(Function)聯絡起來。預設情況下,這些行為是由原始的程式碼(原始碼、中間程式碼)與編譯器(直譯器)決定的,但是使用者可以通過制約編譯器(直譯器)的設定,從而影響到最終程式碼。這麼做是沒有問題的。
還有一種,應用程式在安裝後,會在系統中產生一些快取,或註冊一些資訊。當其中的內容有關使用者資料時,讀取或修改它們也是沒有問題的。這就是所謂"只要是你的東西總是你的";也是Cyanogen Mod、Permission Denied不會涉及版權問題的原因所在。
總之,一個Android應用之所以能執行的前提是:
1,首先,使用者允許使用這個應用
這也可以理解成:使用者安裝了應用(以及因此設定的後臺物件),購買了預裝應用的手機。這一點即不影響應用程式的主動通知義務,也不影響使用者事後的干預。
2,接下來,使用者允許Dalvik對該應用使用"解釋","JIT"的方法,從而該應用程式得以執行。
3,使用者隨時可以對該應用作出任意不違反版權的干預。
所以,在沒有另行規定的前提下,使用者總是可以自行決定,通過給應用程式分配自定義的許可權;或是在應用程式調取內容,物件時予以阻斷。同時,使用者也需要自行承擔因不當操作產生的後果。
附錄:
1、 數字簽名
數字簽名是一種使用了公鑰加密領域的技術實現,用於鑑別數字資訊的方法。一套數字簽名通常定義兩種互補的運算,一個用於簽名,另一個用於驗證。數字簽名可以輕易地驗證完整性(正確性),合法簽署的數字簽名具有不可否認性。 (摘錄自維基百科"數字簽名"條目,有修改)
文章中引用的圖示,圖片或圖片的部分,以及部分文字的引用,僅出於合理使用的目的,可能是持有人版權所有的。
3、 一些行為的說明
不道德行為
應用程式在啟動時,或在主動告知以前,試圖索取、收集電話號碼、郵箱地址、位置資訊等與個人身份直接關聯的內容。如果是與個人關聯,但不能直接聯絡到個人資訊的IMEI等裝置、SIM卡的串號,則稍微好一些。
附圖1,不道德的應用程式在啟動的第一時間就試圖獲取隱私資訊
(新浪微博2.8),無論使用者是否綁定了手機,應用都會第一時間記錄當前手機的號碼
(UC瀏覽器,快拍二維碼),應用總是會不主動通知地記錄裝置的位置資訊
沒有實行主動通知的例子
附圖2 這個應用程式在第一次啟動時便開始收集位置資訊,使用者需要切換六次螢幕才能看到有關位置資訊的提示。這項提示還有意忽略應用程式本身就會記錄使用者位置資訊,即便使用者並不使用需要位置資訊的服務
主動通知的例子
附圖3 主動通知就是在第一屏的醒目處,或用醒目的對比色等強調方式進行通告
作者/fcerebel