1. 程式人生 > >Android權限管理知識學習記錄

Android權限管理知識學習記錄

人的 失效 管理 ext list tracer span man 之間


一、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權限管理知識學習記錄