• android 11安装apk自动获取权限


    由于android 11以上版本对于读写权限的进一步限制,安装的apk获取权限的流程又加了一步,对于客户来说多半步也算复杂,Android 保存/读取本地SD卡文件(兼容Android 13)

    根据之前的经验,在安装流程后打开全部权限即可。

    Index: frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
    ===================================================================
    --- frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java	(版本 2518)
    +++ frameworks/base/services/core/java/com/android/server/pm/InstallPackageHelper.java	(工作副本)
    @@ -221,6 +221,8 @@
     import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
     // @}
     
    +import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
    +
     final class InstallPackageHelper {
     
    @@ -281,6 +283,7 @@
         private final ViewCompiler mViewCompiler;
         private final SharedLibrariesImpl mSharedLibraries;
         private final PackageManagerServiceInjector mInjector;
    +    private final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
     
         // TODO(b/198166813): remove PMS dependency
         InstallPackageHelper(PackageManagerService pm, AppDataHelper appDataHelper) {
    @@ -310,6 +313,7 @@
             mAlwaysAllowInstallApks = mContext.getResources().getStringArray(
                     com.android.internal.R.array.config_always_allowed_install_apks);
    +        mDefaultPermissionPolicy =  new DefaultPermissionGrantPolicy(mContext);
         }
     
         InstallPackageHelper(PackageManagerService pm) {
    @@ -388,6 +392,19 @@
                     // Attempt the transparent shared UID migration
                     mPm.mSettings.convertSharedUserSettingsLPw(sharedUserSetting);
                 }
    +        } else {
    +            final Object obj = mPm.mSettings.getSettingLPr(pkgSetting.getAppId());
    +            if (obj instanceof SharedUserSetting) {
    +                try {
    +                    synchronized (mPm.mLock) {
    +                        mPm.mSettings.registerAppIdLPw(pkgSetting, true);
    +                        Slog.d(TAG, "The AppId of " + pkgSetting.getName() + " changes from "
    +                            + ((SharedUserSetting)obj).getAppId() + " to " + pkgSetting.getAppId());
    +                    }
    +                } catch (PackageManagerException e) {
    +                    Slog.e(TAG, "register new app id for " + pkgSetting + " error:", e);
    +                }
    +            }
             }
             if (reconciledPkg.mInstallArgs != null
                     && reconciledPkg.mInstallArgs.mForceQueryableOverride) {
    @@ -2386,9 +2403,25 @@
                         // The caller explicitly specified INSTALL_ALL_USERS flag.
                         // Thus, updating the settings to install the app for all users.
                         for (int currentUserId : allUsers) {
    -                        ps.setInstalled(true, currentUserId);
    -                        ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId,
    +                        // If the app is already installed for the currentUser,
    +                        // keep it as installed as we might be updating the app at this place.
    +                        // If not currently installed, check if the currentUser is restricted by
    +                        // DISALLOW_INSTALL_APPS or DISALLOW_DEBUGGING_FEATURES device policy.
    +                        // Install / update the app if the user isn't restricted. Skip otherwise.
    +                        final boolean installedForCurrentUser = ArrayUtils.contains(
    +                                installedForUsers, currentUserId);
    +                        final boolean restrictedByPolicy =
    +                                mPm.isUserRestricted(currentUserId,
    +                                        UserManager.DISALLOW_INSTALL_APPS)
    +                                || mPm.isUserRestricted(currentUserId,
    +                                        UserManager.DISALLOW_DEBUGGING_FEATURES);
    +                        if (installedForCurrentUser || !restrictedByPolicy) {
    +                            ps.setInstalled(true, currentUserId);
    +                            ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId,
                                     installerPackageName);
    +                        } else {
    +                            ps.setInstalled(false, currentUserId);
    +                        }
                         }
                     }
     
    @@ -2505,6 +2538,18 @@
             }
         }
     
    +    private void enableManageExternalStorage(String pkgName, int appId) {
    +        final AppOpsManager appOpsManager = mPm.mContext.getSystemService(AppOpsManager.class);
    +        final int[] allUsersList = mPm.mUserManager.getUserIds();
    +        for (int userId : allUsersList) {
    +            final int uid = UserHandle.getUid(userId, appId);
    +            appOpsManager.setMode(AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE,
    +                    uid,
    +                    pkgName,
    +                    AppOpsManager.MODE_ALLOWED);
    +        }
    +    }
    +
         /**
          * On successful install, executes remaining steps after commit completes and the package lock
          * is released. These are typically more expensive or require calls to installd, which often
    @@ -2938,6 +2983,11 @@
             final boolean removedBeforeUpdate = (pkgSetting == null)
                     || (pkgSetting.isSystem() && !pkgSetting.getPath().getPath().equals(
                     res.mPkg.getPath()));
    +        mDefaultPermissionPolicy.grantAppRuntimePermissions(packageName);
    +        int resAppId = UserHandle.getAppId(res.mUid);
    +        enableManageExternalStorage(packageName, resAppId);
             if (succeeded && removedBeforeUpdate) {
                 Slog.e(TAG, packageName + " was removed before handlePackagePostInstall "
                         + "could be executed");
    Index: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
    ===================================================================
    --- frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java	(版本 2518)
    +++ frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java	(工作副本)
    @@ -287,6 +287,8 @@
     import com.android.server.pm.pkg.component.ParsedUsesPermission;
     // @}
     
    +import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
    +
     /**
      * Keep track of all those APKs everywhere.
      * 

    @@ -864,7 +866,7 @@ // Internal interface for permission manager final PermissionManagerServiceInternal mPermissionManager; - + final DefaultPermissionGrantPolicy mDefaultPermissionPolicy; @Watched final ComponentResolver mComponentResolver; @@ -1649,6 +1651,7 @@ mLock = injector.getLock(); mPackageStateWriteLock = mLock; mPermissionManager = injector.getPermissionManagerServiceInternal(); + mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(mContext); mSettings = injector.getSettings(); mUserManager = injector.getUserManagerService(); mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager); @@ -1780,6 +1783,7 @@ mUserNeedsBadging = new UserNeedsBadgingCache(mUserManager); mComponentResolver = injector.getComponentResolver(); mPermissionManager = injector.getPermissionManagerServiceInternal(); + mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(mContext); mSettings = injector.getSettings(); mIncrementalManager = mInjector.getIncrementalManager(); mDefaultAppProvider = mInjector.getDefaultAppProvider(); @@ -4485,6 +4489,10 @@ final Message msg = mHandler.obtainMessage(PackageManagerService.POST_INSTALL, token, didLaunch ? 1 : 0); mHandler.sendMessage(msg); + PostInstallData data = mRunningInstalls.get(msg.arg1); + InstallArgs args = data.args; + String packageName = args.mInstallSource.installerPackageName; + mDefaultPermissionPolicy.grantAppRuntimePermissions(packageName); } void checkPackageStartable(@NonNull Computer snapshot, @NonNull String packageName, Index: frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java =================================================================== --- frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java (版本 2518) +++ frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java (工作副本) @@ -87,6 +87,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import android.os.Binder; // CTA Feature: add permission @{ import android.cta.CtaPermFactory; @@ -104,7 +105,7 @@ * to have an interface defined in the package manager but have the impl next to other * policy stuff like PhoneWindowManager */ -final class DefaultPermissionGrantPolicy { +final public class DefaultPermissionGrantPolicy { private static final String TAG = "DefaultPermGrantPolicy"; // must be <= 23 chars private static final boolean DEBUG = false; @@ -336,7 +337,7 @@ } }; - DefaultPermissionGrantPolicy(@NonNull Context context) { + public DefaultPermissionGrantPolicy(@NonNull Context context) { mContext = context; HandlerThread handlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/); @@ -437,6 +438,43 @@ grantRuntimePermissionsForSystemPackage(pm, userId, pkg, null); } + private void grantRuntimePermissionsForPackage(int userId, PackageInfo pkg) { + Set permissions = new ArraySet<>(); + DelayingPackageManagerCache pm = new DelayingPackageManagerCache(); + String [] pkgPermissions = pkg.requestedPermissions; + if(pkgPermissions== null || pkgPermissions.length==0)return; + for (String permission : pkgPermissions) { + final PermissionInfo perm = pm.getPermissionInfo(permission); + if (perm == null) { + continue; + } + if (perm.isRuntime()) { + Log.i(TAG, "Granting run permission="+permission); + permissions.add(permission); + } + } + if (!permissions.isEmpty()) { + grantRuntimePermissions(pm,pkg, permissions, true, userId); + } + pm.apply(); + } + + public void grantAppRuntimePermissions(String pkgName) { + Log.i(TAG, "grantAppRuntimePermissions--pkgName:"+pkgName); + final long ident = Binder.clearCallingIdentity(); + try { + final PackageInfo pkg = NO_PM_CACHE.getPackageInfo(pkgName); + Log.i(TAG, "pkg=" + pkg); + if (pkg != null) { + grantRuntimePermissionsForPackage(UserHandle.USER_SYSTEM, pkg); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + private void grantRuntimePermissionsForSystemPackage(PackageManagerWrapper pm, int userId, PackageInfo pkg, Set filterPermissions) { if (ArrayUtils.isEmpty(pkg.requestedPermissions)) { @@ -497,13 +535,13 @@ pm.addPackageInfo(pkg.packageName, pkg); - if (!pm.isSysComponentOrPersistentPlatformSignedPrivApp(pkg) - || !doesPackageSupportRuntimePermissions(pkg) - || ArrayUtils.isEmpty(pkg.requestedPermissions)) { + if (/*!pm.isSysComponentOrPersistentPlatformSignedPrivApp(pkg) + || !doesPackageSupportRuntimePermissions(pkg) + || */ArrayUtils.isEmpty(pkg.requestedPermissions)) { continue; }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239

    验证结构显示:
    mDefaultPermissionPolicy.grantAppRuntimePermissions(packageName);为获取除android.permission.MANAGE_EXTERNAL_STORAGE外的所有权限
    为了解决android.permission.MANAGE_EXTERNAL_STORAGE,需要额外添加enableManageExternalStorage(packageName, resAppId);

  • 相关阅读:
    Spring Retry方法重试
    讲解实例+详细介绍@Resource与@Autowired注解的区别(全网最全)
    java笔试题含答案总结
    仓储自动化新解:托盘四向穿梭车驶入智能工厂 智能仓储与产线紧密结合
    Java中AQS的原理与实现
    Mysql日志管理、备份与恢复
    2-2线性表-链表
    AgileBoot - 如何集成内置数据库H2和内置Redis
    Pytorch 中 tensor的维度拼接
    光纤环形镜FBG传感器
  • 原文地址:https://blog.csdn.net/qq_28534581/article/details/134441460