欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

android 8.0权限弹框点击确定,应用会退出

程序员文章站 2022-06-06 09:20:32
...

在项目开发中遇到申请权限的弹框,点击允许,这个应用会退出,百度也没找到原因,只能根据代码定位问题了

首先,显示权限弹框的逻辑在packages/apps/PackageInstaller中,点击事件在GrantPermissionsViewHandlerImpl.java中,
   

@Override
public void onClick(View view) {
    switch (view.getId()) {
        case R.id.permission_allow_button:
            if (mResultListener != null) {
                view.performAccessibilityAction(
                        AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
                mResultListener.onPermissionGrantResult(mGroupName, true, false);
            }
            break;
        case R.id.permission_deny_button:
            mAllowButton.setEnabled(true);
                if (mResultListener != null) {
                    view.performAccessibilityAction(
                            AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);
                    mResultListener.onPermissionGrantResult(mGroupName, false,
                            mShowDonNotAsk && mDoNotAskCheckbox.isChecked());
            }
            break;
        case R.id.permission_more_info_button:
            Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS);
            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppPackageName);
            intent.putExtra(ManagePermissionsActivity.EXTRA_ALL_PERMISSIONS, true);
            mActivity.startActivity(intent);
            break;
        case R.id.do_not_ask_checkbox:
            mAllowButton.setEnabled(!mDoNotAskCheckbox.isChecked());
        break;
    }
}

允许控件的ID是R.id.permission_allow_button,允许权限的具体实现是

mResultListener.onPermissionGrantResult(mGroupName, true, false);

 mResultListener是在GrantPermissionsActivity.java实现的

@Override
public void onPermissionGrantResult(String name, boolean granted, boolean doNotAskAgain) {
    GroupState groupState = mRequestGrantPermissionGroups.get(name);
    if (groupState.mGroup != null) {
        if (granted) {
            groupState.mGroup.grantRuntimePermissions(doNotAskAgain,
                    groupState.affectedPermissions);
            groupState.mState = GroupState.STATE_ALLOWED;
        } else {
            groupState.mGroup.revokeRuntimePermissions(doNotAskAgain,
            groupState.affectedPermissions);
            groupState.mState = GroupState.STATE_DENIED;

            int numRequestedPermissions = mRequestedPermissions.length;
            for (int i = 0; i < numRequestedPermissions; i++) {
                String permission = mRequestedPermissions[i];

                if (groupState.mGroup.hasPermission(permission)) {
                    EventLogger.logPermissionDenied(this, permission,
                            mAppPermissions.getPackageInfo().packageName);
                }
            }
        }
        updateGrantResults(groupState.mGroup);
    }
    if (!showNextPermissionGroupGrantRequest()) {
        setResultAndFinish();
    }
}

继续执行

groupState.mGroup.grantRuntimePermissions(doNotAskAgain,
        groupState.affectedPermissions);

 走到AppPermissionGroup.java中

public boolean grantRuntimePermissions(boolean fixedByTheUser, String[] filterPermissions) {
    final int uid = mPackageInfo.applicationInfo.uid;
    for (Permission permission : mPermissions.values()) {
        if (filterPermissions != null
            && !ArrayUtils.contains(filterPermissions, permission.getName())) {
            continue;
        }

        if (!permission.isGrantingAllowed(mIsEphemeralApp, mAppSupportsRuntimePermissions)) {
            // Skip unallowed permissions.
            continue;
        }

        if (mAppSupportsRuntimePermissions) {
            // Do not touch permissions fixed by the system.
            if (permission.isSystemFixed()) {
                return false;
            }

            // Ensure the permission app op enabled before the permission grant.
            if (permission.hasAppOp() && !permission.isAppOpAllowed()) {
                permission.setAppOpAllowed(true);
                mAppOps.setUidMode(permission.getAppOp(), uid,             AppOpsManager.MODE_ALLOWED);
            }

            // Grant the permission if needed.
            if (!permission.isGranted()) {
                permission.setGranted(true);
                mPackageManager.grantRuntimePermission(mPackageInfo.packageName,
                        permission.getName(), mUserHandle);
            }

            // Update the permission flags.
            if (!fixedByTheUser) {
                // Now the apps can ask for the permission as the user
                // no longer has it fixed in a denied state.
                if (permission.isUserFixed() || permission.isUserSet()) {
                    permission.setUserFixed(false);
                    permission.setUserSet(false);
                    mPackageManager.updatePermissionFlags(permission.getName(),
                            mPackageInfo.packageName,
                            PackageManager.FLAG_PERMISSION_USER_FIXED
                                    | PackageManager.FLAG_PERMISSION_USER_SET,
                            0, mUserHandle);
                }
            }
        } else {

                             .
                             .
                             .
        }
    }
    
    return true;
}

申请权限执行到

mPackageManager.grantRuntimePermission(mPackageInfo.packageName,permission.getName(),mUserHandle);

 在framework/base/services/core/java/com/android/server/pm/PackageManagerService.java

@Override
public void grantRuntimePermission(String packageName, String name, final int userId) {
    grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
}

private void grantRuntimePermission(String packageName, String name, final int userId,
        boolean overridePolicy) {
                      ...
                      ...
    synchronized (mPackages) {
        final PackageParser.Package pkg = mPackages.get(packageName);
        if (pkg == null) {
            throw new IllegalArgumentException("Unknown package: " + packageName);
        }
                      ...
                      ...
        final int result = permissionsState.grantRuntimePermission(bp, userId);
        switch (result) {
            case PermissionsState.PERMISSION_OPERATION_FAILURE: {
                return;
            }

            case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
                final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
                    }
                });
            }
            break;
        }
                     ...
                     ...

    }
}

看到 killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED)这个方法,就知道应用退出的原因了,将这个方法注释掉就可以了 

相关标签: framework