標籤:man 管理機 定義 許可權管理 訪問 trace 檔案中 介面 廠商
一、Android許可權背景知識
在Android 6.0之前,所申請的許可權只需要在AndroidManifest.xml列舉就可以了,從而容易導致一些安全隱患,因此,在Android 6.0時,Google為了更好的保護使用者隱私提出了新的許可權管理機制,同時將其分為兩大類:
(1)Normal Permissions
Normal Permission一般不涉及使用者隱私,是不需要使用者進行授權的,比如手機震動,訪問網路等。
(2)Dangerous Permission
Dangerous Permission一般是涉及到使用者隱私的,需要使用者進行授權(動態申請),比如讀取SIM卡狀態、訪問通訊錄、SD卡讀寫等。
通過adb shell pm list permission -d -g可以查看Dangerous Permission。
Dangerous Permission一般以Permission group形式存在,只要Permission Group中某一個permission被Granted(授予),則整個Permission group下的許可權均被Granted。
二、許可權檢查及許可權相容 1.targetSdkVersion>=23,終端裝置是6.0(api 23)以上系統。
安裝的時候不會獲得許可權,在運行時向使用者申請對應許可權。這部分許可權檢查比較簡單,不涉及許可權相容,使用官方方案就可以,使用Context:checkSelfPermission,建議使用ContextCompat:checkSelfPermission檢查許可權即可,一般檢查流程如下:
(1)判斷是否有對應許可權
(ContextCompat::checkSelfPermision)
(2)判斷是否需要解釋對應許可權用途(ActivityCompat::shouldShowRequestPermissionRationale)
如果需要解釋,則顯示自訂許可權介面即可
(3)不需要解釋的話,直接請求對應許可權
(ActivityCompat::requestPermission)
2.targetSdkVersion<23.終端裝置是6.0(api 23)以上系統
使用的是老的許可權機制,在app安裝時會詢問AndroidManifest.xml檔案中的許可權,但是使用者可以在設定列表中關閉相關許可權,這種情況可能會對app正常運行造成一定影響。
3.終端裝置系統小於6.0(api 23)
老的許可權管理機制是,在app安裝時會詢問AndroidManifest.xml檔案中的許可權,使用者關閉不了,但是目前有不少國產Rom手機在6.0之間就有關閉許可權的開關。
適配過程:
1.使用try-catch來檢查許可權是否關閉
使用READ_PHONE_STATE許可權的方法內部已經try-catch,外面無法捕獲,所以如果該許可權被使用者禁止了,報異常時,在catch中做文章的方法根本沒有用。
2.ContextCompat::checkSelfPermission
在6.0可以使用Context::checkSelfPermission進行許可權檢查,在api 23那使用support v4中的ContextCompat::checkSelfPermission方法失效,只要許可權在AndroidManifest.xml中註冊過,均會認為該許可權granted,因此方法在api 23以下失效。
3.PermissionChecker
PermissionChecker內部實際上使用的是AppOpsManagerCompat,而AppOpsManager是在api 19加入進去的。
在api 23以下,AppOpsManagerImpl::permissionToOp直接返回為null,這直接導致api 23以下許可權檢查將會返回granted,因此,該方法在api 23下,許可權檢查方法也會失效。
4.AppOpsManager
API 19以上,Google官方提供了AppOpsManager類來檢查許可權,裡面有兩個比較重要的方法: AppOpsManager::checkOp(int op,int uid,String packageName)(hide方法,需要反射)和AppOpsManager::checkOp(String op,int uid,String packageName)(public方法,api 23以上可用)。
但是,當api低於23時,OP_READ_PHONE_STATE=51找不到,導致AppOpsManager::checkOp方法反射失敗,導致的原因是每個版本的_NUM_OP不同,OP_READ_PHONE_STATE = 51在6.0(API 23)以下,通過反射是找不到的,因此對於READ_PHONE_STATE許可權檢查僅限於6.0及6.0以上。
三、跳轉到app系統管理權限介面 1.直接跳轉系統設定頁
Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.fromParts("package",getPackageName(), null)); try { startActivity(intent); }catch (Exception e){ e.printStackTrace(); }
記得要添加try-catch,不加可能會crash(崩潰)。這種方式就不需要適配各個廠商的不同版本rom,缺點是,使用者只能跳轉到系統設定頁,然後去找對應app的許可權管理。
2.站在前人的肩
對於不同的手機或手機系統,跳轉許可權管理頁面的activity或者有所不同,如果沒有加上try-catch,就會直接crash。
對於這種變化,作為開發人員一般都是不知道的,即便通過反饋發現了這個問題,也有可能不知道actiivty是什麼,此刻要麼搜尋網上有沒有類似解決方案,要麼求助於對應rom開發廠商的開發人員論壇。
3.查看某個rom的某個版本的許可權管理介面的activity
(1)通過設定找到對應app的許可權管理頁面
(2)找到對應頁面的activity
方法一:通過add工具查看棧頂Activity
adb shell dumpsys activity | grep "mFocusedActivity"
方法二:使用Activity Tracer工具
本文只是將看到的文章進行了學習整理記錄,詳細的還請查看原文。
原文:http://mp.weixin.qq.com/s/OQRHEufCUXBA3d3DMZXMKQ
Android許可權管理知識學習記錄