Android動態權限詳解

2021-02-07 360技術


去年底,上級主管部門為加強國內Android應用隱私管理,出臺了一系列規定,我們的App也做了相應的修改。主要一條修改為,隱私提示與權限獲取順序。修改測試過程中,發覺部分同學對Android權限相關知識和歷史並不了解,就此疫情期間忙裡偷閒,整理些東西供參閱。

首先,從一張圖開始此文。

IOS 12定位權限

時間回到2013年,蘋果公司發布IOS7系統。其中一項令開發者頭疼的修改點:隱私中增加相冊、錄音等權限,App如需使用相應權限,需要申請並由用戶同意(IOS7以前,可以直接訪問相冊)。

針對此點,很多App在首次啟動時一通彈窗,申請各式各樣的權限。後來蘋果為改善用戶體驗,在App Store審核時要求App必須在使用前一刻才能申請權限,有效改善了此類問題。比如一款直播App,當你啟動App時並不需要相機、錄音權限,等到你開播時才需要申請這兩個權限。這一場景,其實就類似今天要提到的Android動態授權。谷歌於2015年推出Android 6.0 Marshmallow,其中一個主要特點便是加入了危險權限管理。這裡的「危險權限管理」就帶來了「運行時權限」這個新特性。危險權限管理」即在進行一些涉及到用戶隱私的操作時,需要獲取用戶的授權才能使用。如通訊錄、簡訊、相機、定位等隱私權限。獲取用戶權限,谷歌提倡在應用運行時向其授權,簡稱,運行時權限(也被叫做「動態權限/動態授權」,後文稱「動態權限」)。那,在這之前,Android權限管理是怎樣的呢?自己杜撰了下國內Android權限管理經歷的大概四個階段。早期Android系統(Android 6.0以前),在安裝App前,會羅列出App申請的所有權限。如果繼續安裝,視為用戶同意賦予App所需權限。例如:sony L36h Android 4.2.2系統。在嘗試安裝App時,彈窗羅列了App申請的全部權限。只能對所需權限進行查看,無法拒絕授權,可選擇取消安裝或繼續安裝。

Sony L36h安裝提示這種方式,對於開發者極為友好,僅需在Manifest中配置App所需權限即可,代碼就可以直接調用了。但是對於用戶來說,這種方法存在極大的安全隱患。例:獲取手機IMEI,需要PHONE_STATE權限;訪問網絡,需要INIERNET權限。只許在Manifest文件中添加權限即可。
 <!-- PHONE_STATE權限-->
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <!-- 網絡權限-->
 <uses-permission android:name="android.permission.INTERNET" />

基於以上背景,為解決部分敏感權限被不合理使用,國內部分公司的安全類App,開始監控應用獲取手機敏感權限並做出提示。如360手機衛士、騰訊手機管家等產品,當監測到有App嘗試使用簡訊權限、定位等敏感權限,會告知用戶,並可以拒絕賦予權限。剛開始,還比較順利。但隨著手機廠商逐漸開始修改ROM,第三方安全App的兼容、性能問題逐步爆發。

例:HTC T328 Android 4.0.2系統。瀏覽器掃碼功能觸發相機調用時,360手機衛士會彈出權限提示窗,用戶可以允許或拒絕授權。注意,此窗由第三方安全軟體彈出,非系統級彈窗,跟後面要說的兩種彈窗有所區別。

360手機衛士 彈窗



隨著時間的推移,手機廠商開始發力,紛紛將第三方軟體的權限提示功能直接做入ROM。例:小米4,基於Android 4.4.4的MIUI7;oppo R9,基於Android 5.1的ColorOS 3.0,瀏覽器掃碼功能觸發相機調用時,會彈出權限提示窗。此窗,由ROM也就是系統自己彈出,為系統級權限彈窗。小米4授權OPPO R9授權

以上3個時期,App在申請權限時都不需做改變,只需配置Manifest。2015年推出的Android 6.0,加入了危險權限管理。因手機廠商對ROM的修改,部分6.0以上機器並不支持此項特性。

到了第四階段,App需要在對權限代碼進行修改後,才能正常使用對應權限。簡單理解為3步:1、判斷是否授權;2、如果未授權需申請權限,根據授權結果繼續執行;3、已授權可以繼續操作。

例:Pixel2,原生Android 10;華為mate8,基於Android 8.0的EMUI8。瀏覽器掃碼功能觸發相機調用時,會彈出權限提示窗。此窗,由App通知系統彈出,為系統級權限彈窗。

pixel2授權彈窗華為mate8授權彈窗第三階段與第四階段,同為系統彈出授權彈窗。二者有什麼區別嗎?首先,從UI上很難判斷所彈授權窗為第三階段或第四階段。第三階段彈的系統授權窗大都帶有一個倒計時自動拒絕邏輯;第四階段彈的系統授權窗基本不帶自動拒絕邏輯。此點可以粗略判斷系統使用的哪種機制。其次,從原理上。第三階段的彈窗,為系統監測到App在使用危險權限行為自動彈出彈窗。第四階段的彈窗,為App發覺自己沒有權限,讓系統彈出的彈窗。粗俗的理解,第三階段,你去朋友家串門,到門口看到大門敞開就直接往裡走,觸發了紅外線報警器,報警器通知了你朋友;第四階段,你去朋友家串門,到門口發覺門關著,就按下門鈴呼叫朋友給你開門。目前,國內主要處於第三階段(涵蓋Android4.0~7.1)和第四階段(涵蓋Android6.0~10),此點將在後文用到。

因為動態權限特性,僅從Android 6.0開始擁有,所以,可以簡單粗暴的通過不提升targetSDK(targetSDK<23)的方式,便可不觸發此特性。

targetSDK18正常獲取IMEI僅提升targetSDK到26直接運行崩潰如果不改變任何代碼,直接將targetSDK提升到26,然後運行App,做同樣操作時會發生異常甚至崩潰,崩潰舉例如下:

無PHONE_STATE獲取IMEI崩潰產生這個崩潰的原因,是在Android 6.0及以上,未獲取權限的情況下直接執行了需要權限的操作。那麼如何解決呢,就涉及到了真正的修改方案。

1. 在使用權限前,檢測權限。

首先,我們需要判斷自己是否擁有權限。判斷時間點為執行需要權限的對應操作前。如我們在獲取IMEI前,需要判斷是否擁有PHONE_STATE權限。

我們可以調用ContextCompat.checkSelfPermission()方法檢測授權狀態,返回的結果為PackageManager中的兩個常量:PERMISSION_GRANTED(已授權)和PERMISSION_DENIED(未授權)。

2. 已授權的情況下,執行你的原有操作。

當已授權時,就可以執行你原有的操作了。代碼如下:

 // 檢測PHONE_STATE 如果已授權
 if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
     //做你想做的
 }

3. 未授權的情況下,申請權限。

如果App未獲得授權,我們就需要向用戶申請授權。可以調用requestPermissions()方法來請求授權。代碼如下:

 // 檢測PHONE_STATE 如果未授權
 if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
     //申請權限
     ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), PERMISSIONS_REQUEST_PHONE_STATE)
 }

requestPermissions()中的第三個參數是一個int型請求碼,方便回調處理。調用申請授權方法後,ROM會調起一個系統級彈窗(如下圖),這個dialog你無法定製。當用戶點擊同意後,系統會記錄,下次再判斷權限時就會返回已授權狀態;當App卸載時,記錄會被清除。Android 10授權彈窗

以上,就完成了最樸素版的授權邏輯。整體代碼如下:

 // 檢測PHONE_STATE 如果未授權
 if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
     //申請權限
     ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_PHONE_STATE), PERMISSIONS_REQUEST_PHONE_STATE)
 }else {
     //如果已授權做你想做的
 }

那麼彈出申請彈窗之後呢?上面說道,彈出的dialog為系統的,我們無法在dialog中加代碼,但當彈窗被用戶點擊後,會觸發回調,我們在指定函數中處理回調即可。4. 重寫函數,處理授權彈窗的點擊結果。

直接在Activity或Fragment中重寫onRequestPermissionsResult()函數,來處理權限申請結果。requestPermissions()的第三個參數,將在這裡被用到。代碼如下:

 // 處理授權彈窗回調
 override fun onRequestPermissionsResult(
     requestCode: Int,
     permissions: Array<out String>,
     grantResults: IntArray
 ) {
     when(requestCode){
         // 識別剛剛用到的請求碼,根據請求碼識別不同彈窗回調並處理
         PERMISSIONS_REQUEST_PHONE_STATE ->{
             // 如果用戶點擊「允許」
             if (grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                 Toast.makeText(this, "用戶允許權限!",Toast.LENGTH_SHORT).show()
                 // 可以繼續執行你原來想做的事情了
 
             }else{
                 Toast.makeText(this, "用戶拒絕權限!",Toast.LENGTH_SHORT).show()
                 // 用戶拒絕了,你想咋辦?
             }
             return;
         }
         // 可以識別其他請求碼並處理
     }
 }

這樣,就完成了授權流程。然後,為提升授權概率,對流程進行優化。

5. 優化授權流程,提高授權機率。首先,系統授權窗我們無法定製,但是我們可以在這之前做個引導。在觸發系統彈窗之前,彈出一個引導UI,來告知用戶將要申請權限,並說明所需權限可帶來哪些更好體驗。尤其當你申請的權限看似與主要功能並無關係時,比如一個相機App如果需要申請定位權限的時候。

其次,谷歌官方還提供了個函數shouldShowRequestPermissionRationale(),這個函數可以用來判斷,用戶上次是否拒絕了且未選則不再詢問。可以在授權前,通過此判斷,來決定給用戶展示首次授權引導或非首次授權引導。

最後,當用戶還是選擇了拒絕授權時,如果是必要權限(比如導航軟體申請定位權限),我們可以通過處理授權回調,在用戶點擊拒絕時彈出引導,告知用戶功能不可用,並引導用戶重新授權或到設置中手動開啟權限。引導授權流程

綜上,動態權限主要實現步驟

在AndroidManifest明確我們需要哪些權限。(非動態權限也需要此步)在執行操作前檢是否獲得對應授權 -> checkSelfPermission()。如果已授權可以繼續操作;如果未授權,判斷之前是否授權被拒 -> shouldShowRequestPermissionRationale() (非必須操作)
a) 判斷如果沒有被拒過,彈出首次授權引導。
b) 判斷如果被據過,彈出非首次授權引導。引導後,申請權限-> requestPermissions()。處理申請的結果信息-> 回調函數onRequestPermissionsResult()。

系統一共提供如下4個函數完成動態權限相關操作。

    /**
     * 檢查指定的權限是否授權(Context對象調用)
     */
    public static int checkSelfPermission (Context context, 
                String permission)

    /**
     * 在沒有授權的情況下,有些時候可能需要提示給用戶為什麼需要改權限,就通過該函數來實現。
     * 關於shouldShowRequestPermissionRationale的返回值問題,我們分三種情況
     * 1. 第一次打開App時 -> false
     * 2. 上次彈出權限點擊了禁止(但沒有勾選「下次不在詢問」) -> true
     * 3. 上次選擇禁止並勾選:下次不在詢問 -> false
     */
    public static boolean shouldShowRequestPermissionRationale (Activity activity, 
                String permission)

    /**
     * 申請指定的權限(Activity或者Fragment對象調用)
     * @param permissions 權限列表,可以同時申請多個權限
     * @param requestCode 該次權限申請對應的requestCode。和 onRequestPermissionsResult()回調函數裡面的requestCode對應
     */
    public static void requestPermissions (Activity activity, 
                String[] permissions, 
                int requestCode)

    /**
     * 處理請求權限的響應,當用戶對請求權限的dialog做出響應之後,系統會回調該函數(Activity或者Fragment中重寫)
     * @param requestCode 申請權限對應的requestCode
     * @param permissions 權限列表
     * @param grantResults 權限列表對應的返回值,判斷permissions裡面的每個權限是否申請成功
     */
    public abstract void onRequestPermissionsResult (int requestCode, 
                String[] permissions, 
                int[] grantResults)


寫到這裡,動態授權實現demo部分均已完成,實際業務場景肯定比以上流程複雜的多

動態權限為Android 6.0新特性,那低於6.0的系統,該如何寫適配代碼呢?首先想到的,是判斷系統版本,針對6.0以上使用動態權限代碼,針對低版本,使用老代碼。
 fun test(){
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
         // 走動態授權
         return
     else
         // 走非動態授權
         return
 }

其實,可以不必如此麻煩。對於低版本,可以不必單獨寫代碼適配。在不支持動態授權的系統上,Manifest中申請過的權限,checkSelfPermission()方法,會直接返回PERMISSION_GRANTED。

另外,根據系統版本區分是否支持動態權限,實際是不靠譜的。前文有提到,部分手機廠商在ROM提升到Android 6.0以後,閹割了動態權限特性。目前沒有找到準確的API判斷當前系統是否支持動態權限。這會帶來什麼問題呢?

舉一個前不久遇到的實例。App的某一功能,是對別人顯示我所在城市(地理位置屬於敏感數據),用戶反饋關閉系統定位權限後,仍會顯示他所在城市。我們需要考慮如何解決用戶的問題,所以增加個需求,如果用戶關閉了定位權限,則不獲取城市。那麼問題來了,怎麼判斷用戶是否關閉了定位權限呢?為了避開不支持動態權限的ROM,需求只能退一步,6.0及以上系統做以上邏輯,6.0以下直接不獲取地理位置。但是根據測試經驗6.0以上系統仍不一定支持動態權限, 7.0及以上系統,絕大部分ROM支持動態權限。所以妥協決定7.0以下全部不獲取,7.0以上調checkSelfPermission()判斷是否授權,少數不支持動態權限的設備會誤認為已授權,需要增加設置項關閉功能。(提升到Android8.0應該是絕對安全的,不過覆蓋量太少)

以下為目前主流國內廠商對動態權限支持情況。(測試方法:在全新安裝未進行過授權操作的情況下,使用checkSelfPermission()檢查PHONE_STATE、定位、相機權限,返回如果是PERMISSION_GRANTED,則認為不支持動態權限)

 基於Android6.0的ROM基於Android7.0的ROM小米
支持華為支持支持OPPO不支持支持VIVO不支持7.1.1不支持
7.1.2支持部分權限魅族
支持錘子
不支持360不支持不支持中興
支持1. 授權彈窗元素Android 8.0授權彈窗2. 是否存在不再詢問選項

關於權限彈窗,針對同一個App的同一個權限,有時彈窗不帶「拒絕&不再詢問」選項,有時帶此選項。如下圖是谷歌原生系統、小米MIUI系統的兩種彈窗對比。這是什麼原因呢?Android原生實現:App全新安裝後首次申請權限,彈窗不帶此選項,即圖左效果。當用戶拒絕授權後,App下次再申請該權限時,則帶此選項,即圖右效果。但是,國內部分手機廠商並未遵循此標準,比如華為的Android 10之前的系統、OPPO/VIVO的部分權限,授權彈窗不管是否首次,都帶此選項。此為系統行為,App無法決定。

pixel2不再詢問MIUI不再詢問3. 彈窗選項與App設置中權限選項對應關係

系統的授權彈窗,實際具有3項(允許、拒絕、 拒絕不再詢問)。但設置中的App權限選項,有的系統有2項(允許、拒絕),有的有3項(允許、詢問、拒絕)。授權彈窗選項與設置中的選項對應關係如下。

以原生Android 10系統為例:

彈窗 拒絕&不再詢問 -> 設置 拒絕 (跟上一項UI一致,本質有區別)。pixel2彈窗對應設置

以基於Android 9.0的MIUI10.4.8為例:

MIUI彈窗對應設置4. 彈窗選項對四個函數的影響。

彈窗彈出,用戶操作指定選項後,下次再調用四個函數會有如下現象:

UI選項與函數調用結果Android 6.0系統開始,權限被分為Normal permissions、Signature permissions、Dangerous permissions,其中Signature permissions比較超綱,僅介紹普通權限和危險權限。其中普通權限使用方法跟低版本一樣,只用在Manifest裡申請就可使用。大部分低風險權限,不需要通過確認框這種形式讓用戶顯示的同意。比如訪問網絡、檢查WiFi狀態等權限。另一種危險權限,也就是本文介紹的對象,它的產生主要為了保護用戶隱私,換言之,涉及到用戶隱私的一些權限,屬於危險權限。例如:相機權限、定位權限、PHONE_STATE(可讀取手機IMEI等識別碼)權限等。

危險權限關於權限,還有一個權限組的概念。例如,讀取外置存儲權限(READ_EXTERNAL_STORAGE)和寫入外置存儲權限(WRITE_EXTERNAL_STORAGE),同屬存儲權限組(STORAGE)。
權限組有什麼作用呢?在Android O之前,同一權限組的權限,只要用戶授權一個,則整個權限組都被授權。例如:
步驟一:Manifest中加入了READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE
步驟二:在程序中只申請了READ_EXTERNAL_STORAGE權限,用戶同意後
步驟三:在程序中未申請WRITE_EXTERNAL_STORAGE權限,並嘗試直接使用
結果:可以直接使用,同組權限不需再申請。而Android O對此進行了修改。同一權限組不同權限,必須都要動態申請權限。但是如果第一個被用戶同意了,後面的同組權限再申請時,就不會再彈窗而是被直接同意了。例如:
步驟一:Manifest中加入了READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE
步驟二:在程序中只申請了READ_EXTERNAL_STORAGE權限,用戶同意後
步驟三:在程序中未申請WRITE_EXTERNAL_STORAGE權限,並嘗試直接使用
結果:崩潰。
修改步驟三:在程序中申請WRITE_EXTERNAL_STORAGE權限
結果:不會彈出授權彈窗,同一權限組直接被自動授權

But,部分ROM修改了此邏輯。比如,華為9.0以下系統,遵循的是原生系統Android 8.0之前的邏輯。但是,華為9.0以後系統和小米6.0以後系統,都用的比原生系統Android 8.0更嚴格的邏輯。每個權限都需要單獨申請權限,而且會單獨彈窗要求用戶確認。

例如:
步驟一:Manifest中加入了READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE
步驟二:在程序中只申請了READ_EXTERNAL_STORAGE權限,用戶同意後
步驟三:在程序中申請WRITE_EXTERNAL_STORAGE權限
結果:會彈出授權彈窗,需要用戶再次授權
帶來問題:相同權限組不同權限的授權彈窗是一毛一樣的。這就導致用戶很懵逼,明明剛剛授權過了,為什麼又要問我一次。

不同ROM權限組內影響

所以,部分手機上,你會發覺有些App,先後彈出兩個訪問文件存儲的權限彈窗。那是因為寫App的時候,先後申請了READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE權限導致。如何解決?

查看requestPermissions()方法的第二個參數,為一個數組。也就是說,可以傳入一個權限列表。

    /**
     * 申請指定的權限(Activity或者Fragment對象調用)
     * @param permissions 權限列表,可以同時申請多個權限
     * @param requestCode 該次權限申請對應的requestCode。和 onRequestPermissionsResult()回調函數裡面的requestCode對應
     */
    public static void requestPermissions (Activity activity, 
                String[] permissions, 
                int requestCode)

經測試,如果直接調該方法同時傳入READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE只會彈出一個授權窗,而且用戶同意後可以同時獲得兩個權限。如果傳入不同組權限,則按先後每組彈出一個彈窗。而且,這種單次傳入多組權限的情況,彈窗中大都會出現一個m/n的編號,以標識彈到第幾個,還剩幾個。如下圖分別是MIUI10(基於android9)和EMUI10(基於android10)的彈窗樣式:
紅米Note8Pro連續授權窗


華為Mate20連續授權窗


後期的一些權限策略變化,僅列部分戶感知較大的。

IOS 8(2014年),定位權限選項分為「使用期間」(新增項)、「始終允許」、「不允許」。(減少App後臺定位)IOS 10(2016年),App訪問網絡需要授權。安裝未知來源應用需要申請權限。(App自升級、三方應用市場、廣告App安裝其他App需申請權限)定位權限選項分為「使用期間」(新增項)、「始終允許」、「拒絕」。(減少App後臺定位)部分電話、藍牙、WLAN的API,需要申請精確位置權限。IOS 13(2019年),定位權限選項分為「使用App時允許」、「允許一次」(新增選項)、「不允許」,去除了「始終允許」。(「允許一次」相當於試用權限或臨時權限,重啟App後需要重新申請權限)分區存儲強制執行。Download目錄、SD卡目錄訪問受限。對位置、麥克風、相機增加一次性權限許可,見IOS 13定位權限(即,如果用戶選了一次性許可,重啟App後需要重新申請權限)。自動阻止App重複的權限請求。也就是說如果用戶點擊2次拒絕授權,那麼系統會自動停止詢問授權,當然了,用戶也可以前往設置中手動調整。

  兩大平臺,都在多個版本中對用戶隱私進行了優化,僅定位權限的優化就多次提及。

  可見,在手機逐漸轉化為人體器官之一的今天,IOS和Android兩大移動平臺對於權限、隱私的管理越發嚴苛,而且趨同的速度約來越快。估計以後Android App想訪問網絡也需申請授權。但手機廠商自行定製修改ROM,仍是開發者最頭疼的問題。

參考文獻:谷歌官方文檔:https://developer.android.com/training/permissions/requesting.html

留言區

相關焦點

  • 關於Android6.0系統動態權限管理的解決方案(精品)
    無需第三方應用和Root權限,原生的Android6.0就支持應用權限管理,用戶在安裝應用時選擇關閉一些應用權限,來達到保護自己隱私的目的,功能非常強大。         那麼下面就簡單的講解下動態管理權限的問題。
  • Android 6.0: 動態權限管理的完美解決方案
    動態權限管理就是這樣, 一方面讓用戶更加容易的控制自己的隱私, 一方面需要重新適配應用權限. 時代總是不斷發展, 程序總是以人為本, 讓我們為應用添加動態權限管理吧! 這裡提供了一個非常不錯的解決方案, 提供源碼, 項目可以直接使用.
  • Android 6.0 運行時權限處理
    >又新增了運行時權限動態檢測,以下權限都需要在運行時判斷:身體傳感器日曆攝像頭通訊錄地理位置麥克風電話簡訊存儲空間運行時權限處理Android6.0系統默認為targetSdkVersion小於23的應用默認授予了所申請的所有權限,所以如果你以前的APP設置的targetSdkVersion低於23,在運行時也不會崩潰,但這也只是一個臨時的救急策略
  • 詳解Android 6.0運行時權限
    從Android 6.0開始,不再是安裝應用時用戶確定獲得全部的權限.而是在使用軟體過程中需要該權限時,彈出對話框讓用戶選擇權限.不僅如此,用戶選擇權限後還可以關閉。也就是說:用戶第一次點擊一個需要權限的地方,該方法返回false(因為用戶沒拒絕~),當用戶拒絕掉該權限,下次點擊此權限處,該方法會返回true。可在裡面進行對該權限的說明,然後彈出權限讓用戶選擇,並且對話框有don't ask again選項:
  • Android APP漏洞之戰——Broadcast Recevier漏洞詳解
    (https://bbs.pediy.com/thread-269255.htm)Android APP漏洞之戰(1)——Activity漏洞挖掘詳解。=["true" | "false"] android:icon="drawable resource" android:label="string resource"//繼承BroadcastReceiver子類的類名 android:name=".mBroadcastReceiver"//具有相應權限的廣播發送者發送的廣播才能被此BroadcastReceiver所接收;
  • Android端權限隱私的合規化處理實踐
    具體實踐一.Android各版本對權限的適配處理1.1 早期的註冊權限Android6.0(SDK版本為23)之前的版本,安裝App頁面會列出當前app所註冊的所有權限,無同意與否按鈕,只有安裝和取消,開發App時只需要在清單文件中註冊所需的對應權限即可:<uses-permission android:name="android.permission.READ_PHONE_STATE
  • Android權限機制與適配經驗
    然而,同期的iOS對於權限的處理會更加靈活,權限的授予並不是在安裝時,而是在APP運行時,用戶可以根據自身的需要,決定是否授予APP某一權限,同時,用戶也可以很方便回收授予的權限。顯然,動態權限管理的機制,對於用戶的隱私保護是更加適用的,Android過於簡單的權限機制也受到了不少人的吐槽。終於,Android6.0也發布了動態權限的機制。
  • 你真的了解Android權限機制嗎?
    系統包管理器會負責記錄組件的權限,所以靜態權限檢查可以從包管理器拿到權限,由運行環境或容器來執行權限檢查,這樣子可以把業務邏輯和安全決策分離開來,但是靈活性不足。那 Android 組件可不可以不預先聲明權限在 AndroidManifest.xml 中呢?答案是:可以的。Android 的動態權限執行,可以讓組件自身執行權限檢查,而不是運行環境。
  • Android應用權限大全
    訪問登記屬性android.permission.ACCESS_CHECKIN_PROPERTIES ,讀取或寫入登記check-in資料庫屬性表的權限獲取錯略位置android.permission.ACCESS_COARSE_LOCATION,通過WiFi或移動基站的方式獲取用戶錯略的經緯度信息
  • Android 7.0動態權限大總結
    /** * @Author: duke * @DateTime: 2017-06-06 14:43 * @Description: android 7.0 uri權限適配, * (通過intent暴漏uri或file給第三方app時的)私有目錄被禁止訪問 * 已對local path和net path做了適配
  • 一次Android權限刪除經歷
    ,只允許滿足條件的使用場景才能申請權限,小編所在的項目被檢測出使用了RECEIVE_SMS權限,但是從app下的Androidmanifest文件中並未發現有該權限的註冊,所以該權限是哪裡來的呢?2.初步定位首先使用android studio查看了打包出來的apk中的Androidmanifest文件,發現其中確實存在RECEIVE_SMS權限,也就是說打包到apk中的Androidmanifest文件並不是app下的該文件,從android開發者官網中合併多個manifest文件的文檔來看,實際上打包到apk中的manifest文件是由多個menifest文件合併而來的,其合併順序如下
  • 一次 Android 權限刪除經歷
    ,只允許滿足條件的使用場景才能申請權限,小編所在的項目被檢測出使用了RECEIVE_SMS權限,但是從app下的Androidmanifest文件中並未發現有該權限的註冊,所以該權限是哪裡來的呢?2.初步定位 首先使用android studio查看了打包出來的apk中的Androidmanifest文件,發現其中確實存在RECEIVE_SMS權限,也就是說打包到apk中的Androidmanifest 文件並不是app下的該文件,從 android開發者官網中合併多個manifest文件的文檔來看,實際上打包到apk中的 manifest文件是由多個menifest文件合併而來的
  • Android 設備信息獲取詳解
    -- 讀取手機IMEI的設備權限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  • Android 自定義權限真的安全嗎?
    今天我們聊聊 Android 的自定義權限的安全問題。如果你對 Android 的權限機制尚覺陌生,不妨先看看官方 API 指南的這一節: Android 的權限機制 (http://developer.android.com/training/articles/security-tips.html)。
  • Android 6.0運行時權限詳解
    Android 6.0版本中運行時權限的出現解決了這一問題,一些高危權限會在應用的運行過程中動態申請,這樣用戶就可以選擇是否允許,比如一個單機遊戲要獲取通訊錄權限,那肯定要禁止了。並不是所有的權限都需要動態申請,需要申請的權限如下表所示: 注意:同一組內的任何一個權限被授權了,其他權限也自動被授權。
  • Android權限機制,你真的了解嗎?
    2.2 Protection level我們經常在AndroidManifest中使用權限,如果我們想讓應用程式可以發簡訊,那麼應該這樣寫:<uses-permission android:name="android.permission.SEND_SMS"/>其權限的定義是在frameworks/base/core
  • Android 6.0以前國產手機權限處理
    Android是在6.0加入的權限機制,但是不少國產手機比如華為小米等,在6.0之前的設備已經在設置裡面有權限開關。調皮的某個用戶會關掉這個權限,然後去拍照什麼的,直接崩掉了。之前大牛郭霖在csdn做了一期權限機制的教學直播,結束後我問了他這個問題,他的回答是簡單try catch即可無需深究。那我想結合實際項目研究下這個問題。
  • 五種控制Android應用的權限的方法
    )  通話記錄   (android.permission.READ_CONTACTS)  系統日誌  (android.permission.READ_LOGS)  當前帳戶列表  (android.permission.GET_ACCOUNTS)  當前帳戶的授權碼 (android.permission.USE_CREDENTIALS)
  • 如何實現 Android 動態壁紙效果?
    Android為我們提供了很多個性化特性,動態壁紙就是其中之一。動態壁紙是Android主屏幕中,可以動的、交互的背景。自Android 2.1開始支持。例如雙擊屏幕(Style中雙擊屏幕壁紙會變清晰)。相關的api在android.service.wallpaper包中。
  • 這也許是Android一句話權限適配的最優 解決方案
    (context instanceof Activity)) {        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);    }    context.startActivity(intent);}那麼在適配動態權限以前,在我們任意用到打電話的業務頁面我們可能就是這麼用:public