天天看點

Android 預設賦予運作時權限

 在進行系統定制時,内置應用會要求各式各樣運作時權限,例如撥打電話和管理通話權限

Android 預設賦予運作時權限

為了避免使用者沒有留意而拒絕了應用的關鍵權限,我們必須對使用者授權時的各種狀态進行詳細的分析。

使用者在授予權限時存在三種狀态:

允許—授權成功,授權結束。

拒絕—授權失敗,下次申請仍會彈出提示框。如果權限是程式必須擁有的,則需要再次申請。

拒絕&不再詢問—拒絕一次後,下次會有該提示。若選擇拒絕并且不再詢問,下次申請則不會彈出提示框。如果權限是程式必須擁有的,則需要使用者到應用管理中手動設定。

對于内置應用,客戶希望不會彈出這些東西,而且一旦錯過允許就不會再次彈出,比較影響客戶體驗,是以我在SystemUIApplication裡自定義了一個方法,這個方法可以在應用解壓的時候就賦予運作時權限.

private PackageInfo getCallingPackageInfo(String pkgName,Context context) {
        try {
            return context.getPackageManager().getPackageInfo(pkgName,
                    PackageManager.GET_PERMISSIONS);
        } catch (NameNotFoundException e) {
            Log.d("lei", "No package: " + e);
            return null;
        }
    }

    public void grantAllRuntimePermissions(String pkgName,Context context){
        PackageManager pkgManager = context.getPackageManager();
        PackageInfo mPackageInfo = getCallingPackageInfo(pkgName,context);
        UserHandle userHandle = new UserHandle(
                        UserHandle.getUserId(mPackageInfo.applicationInfo.uid));
        List<String> requestPermissions = new ArrayList<String>();
        List<PermissionInfo> permissionInfos = new ArrayList<PermissionInfo>();
        final int permissionCount = mPackageInfo.requestedPermissions.length;
        for (int i = 0; i < permissionCount; i++) {
            String requestedPermission = mPackageInfo.requestedPermissions[i];
            try {
                PermissionInfo permissionInfo = pkgManager.getPermissionInfo(requestedPermission, 0);
                if(isRuntime(permissionInfo.protectionLevel) || isRuntimeOnly(permissionInfo.protectionLevel)){
		    Log.d("lei","runtime requestedPermission = "+requestedPermission);
                    permissionInfos.add(permissionInfo);
                    requestPermissions.add(requestedPermission);
                }
            } catch (PackageManager.NameNotFoundException e) {
            }

        }

        for(String permission : requestPermissions){
            pkgManager.grantRuntimePermission(mPackageInfo.packageName,
                        permission, userHandle);
        }
    }

    public boolean isRuntime(int protectionLevel) {
        return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                == PermissionInfo.PROTECTION_DANGEROUS;
    }


    public boolean isRuntimeOnly(int protectionLevel) {
        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY) != 0;
    }
           

這段代碼可以放在任何接收開機廣播BOOT_COMPLETED開的類裡面,SystemUIApplication類隻是系統中任一接收開機廣播的類檔案,可以随便選擇的。

上面getCallingPackageInfo方法是擷取目前應用的PackageInfo,PackageInfo這個類裡面儲存的應用資訊比較多,不過咱們在這裡用到的是以下三項:

permissions

requestedPermissions

requestedPermissionsFlag

這樣就可以看不到權限彈窗了~,