1. 程式人生 > 程式設計 >Android 7.0 執行時許可權彈窗問題的解決

Android 7.0 執行時許可權彈窗問題的解決

Android 7.0系統在執行應用的時候,對許可權做了諸多限制,normal,dangerous,signature,signatureOrSystem,取決於保護級別,在確定是否授予許可權時,系統可能採取不同的操作。

  • normal 表示許可權是低風險的,不會對系統、使用者或其他應用程式造成危害;
  • dangerous 表示許可權是高風險的,系統將可能要求使用者輸入相關資訊,才會授予此許可權;
  • signature 表示只有當應用程式所用數字簽名與宣告引許可權的應用程式所用數字簽名相同時,才能將許可權授給它;
  • signatureOrSystem 表示將許可權授給具有相同數字簽名的應用程式或android 包類。這一保護級別適和於非常特殊的情況,比如多個供應商需要通過系統映像共享功能時

執行時許可權彈窗問題是很多系統定製的客戶要求遮蔽的,一直以來沒有特別好的方法,下面我分享一下我自己驗證可行的方案

方案1,修改frameworks/base/services/core/java/com/android/server/pm/PackageManagerService和frameworks/base/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy檔案,PackageManagerService檔案修改程式碼如下:

 @Override
  public void systemReady() {
 ...
 synchronized (mPackages) {
      ...
      for (int userId : UserManagerService.getInstance().getUserIds()) {
        //if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {//註釋掉這個判斷
          grantPermissionsUserIds = ArrayUtils.appendInt(
              grantPermissionsUserIds,userId);
        //}
      }
    }

DefaultPermissionGrantPolicy檔案修改程式碼如下:

 private void grantPermissionsToSysComponentsAndPrivApps(int userId) {
    Log.i(TAG,"Granting permissions to platform components for user " + userId);
 
    synchronized (mService.mPackages) {
      for (PackageParser.Package pkg : mService.mPackages.values()) {
   // if (!isSysComponentOrPersistentPlatformSignedPrivAppLPr(pkg) //刪掉isSysComponentOrPersistentPlatformSignedPrivAppLPr判斷
 if(!doesPackageSupportRuntimePermissions(pkg)
            || pkg.requestedPermissions.isEmpty()) {
          continue;
        }
        Set<String> permissions = new ArraySet<>();
        final int permissionCount = pkg.requestedPermissions.size();
        for (int i = 0; i < permissionCount; i++) {
          String permission = pkg.requestedPermissions.get(i);
          BasePermission bp = mService.mSettings.mPermissions.get(permission);
          if (bp != null && bp.isRuntime()) {
            permissions.add(permission);
          }
        }
        if (!permissions.isEmpty()) {
          grantRuntimePermissionsLPw(pkg,permissions,true,userId);
        }
      }
    }
  }

簡單說明下這個方案的修改原理,在PMS的systemReady方法中會遍歷所有擁有預設執行時許可權應用,通過遍歷它們的UserId來賦予許可權,註釋掉判斷是否為擁有執行時許可權的應用方法後,會遍歷所有應用,遍歷應用且賦予許可權的操作是在DefaultPermissionGrantPolicy中grantPermissionsToSysComponentsAndPrivApps方法,註釋掉判斷簽名應用和系統應用的方法,普通應用也可以獲取所有執行時許可權,這樣所有應用都不會有執行時許可權的彈窗了。

方案2,只修改frameworks/base/services/core/java/com/android/server/pm/PackageManagerService檔案,修改grantPermissionsLPw方法,程式碼如下:

 private void grantPermissionsLPw(PackageParser.Package pkg,boolean replace,String packageOfInterest) {
   ...
   /*add for grant thirdparty app permssion S*/
   final String thirdPkgName = SystemProperties.get("persist.thirdparty.packagenames","");
      
   if(isSystemApp(pkg) || pkg.packageName.contains(thirdPkgName)){//xxx為包名
    final int permCount = pkg.requestedPermissions.size();
    for(int i = 0;i < permCount;i++){
      final String name = pkg.requestedPermissions.get(i);
      final BasePermission bp = mSettings.mPermissions.get(name);
      if(bp != null && permissionsState.grantInstallPermission(bp) != PermissionsState.PERMISSION_OPERATION_FAILURE){
        changeInstallPermission = true;
      }
   }
   /*add for grant thirdparty app permission E*/
   permissionsState.setGlobalGids(mGlobalGids);
   ...
 }

簡單解釋下第二中方案的思路,PMS在應用安裝的時候會根據應用是否為簽名應用、系統應用或三方應用來更新許可權,這裡可以做成白名單的形式,目前通過SystemProperties來獲取三方包名可以通過adb或者串列埠來測試三方應用許可權是否可以正常獲取。兩種方案大家可以自由選擇。

到此這篇關於Android 7.0 執行時許可權彈窗問題的解決的文章就介紹到這了,更多相關Android7.0 許可權彈窗 內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!