AppA在清单中定义权限A,如
package="com.example.definepermission"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<permission
android:name="com.example.permission.test.permissionA"
android:protectionLevel="normal"
>
</permission>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:permission="com.example.permission.test.permissionA">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
AppB请求AppA活动,如
<uses-permission android:name="com.example.permission.test.permissionA"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
private void startNewActivity(){
Intent intent = new Intent();
intent.setClassName("com.example.definepermission", "com.example.definepermission.MainActivity");
startActivity(intent);
}
来自pkms转储
$ dumpp com.example.redfinepermission
Activity Resolver Table:
Non-Data Actions:
android.intent.action.MAIN:
701f87f com.example.redfinepermission/.MainActivity
Key Set Manager:
[com.example.redfinepermission]
Signing KeySets: 37
Packages:
Package [com.example.redfinepermission] (6c7b04c):
userId=10089
pkg=Package{1856895 com.example.redfinepermission}
codePath=/data/app/com.example.redfinepermission-1
resourcePath=/data/app/com.example.redfinepermission-1
legacyNativeLibraryDir=/data/app/com.example.redfinepermission-1/lib
primaryCpuAbi=null
secondaryCpuAbi=null
versionCode=1 targetSdk=21
versionName=1.0
splits=[base]
applicationInfo=ApplicationInfo{3e91daa com.example.redfinepermission}
flags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
dataDir=/data/user/0/com.example.redfinepermission
supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
timeStamp=2016-12-13 20:57:27
firstInstallTime=2016-12-13 20:57:27
lastUpdateTime=2016-12-13 20:57:27
signatures=PackageSignatures{cc79d9b [3e58538]}
installPermissionsFixed=true installStatus=1
pkgFlags=[ HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
requested permissions:
com.example.permission.test.permissionA
User 0: installed=true hidden=false stopped=true notLaunched=true enabled=0
runtime permissions:
User 10: installed=true hidden=false stopped=true notLaunched=true enabled=0
runtime permissions:
$ dumpp com.example.definepermission
Activity Resolver Table:
Non-Data Actions:
android.intent.action.MAIN:
6e05ed9 com.example.definepermission/.MainActivity
Permissions:
Permission [com.example.permission.test.permissionA] (f44b09e):
sourcePackage=com.example.definepermission
uid=10090 gids=null type=0 prot=normal
perm=Permission{643877f com.example.permission.test.permissionA}
packageSetting=PackageSetting{943934c com.example.definepermission/10090}
Key Set Manager:
[com.example.definepermission]
Signing KeySets: 24
Packages:
Package [com.example.definepermission] (943934c):
userId=10090
pkg=Package{16f0f95 com.example.definepermission}
codePath=/data/app/com.example.definepermission-1
resourcePath=/data/app/com.example.definepermission-1
legacyNativeLibraryDir=/data/app/com.example.definepermission-1/lib
primaryCpuAbi=null
secondaryCpuAbi=null
versionCode=1 targetSdk=21
versionName=1.0
splits=[base]
applicationInfo=ApplicationInfo{54738aa com.example.definepermission}
flags=[ DEBUGGABLE HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
dataDir=/data/user/0/com.example.definepermission
supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
timeStamp=2016-12-13 20:57:46
firstInstallTime=2016-12-13 20:57:46
lastUpdateTime=2016-12-13 20:57:46
signatures=PackageSignatures{131c9b [5bc9838]}
installPermissionsFixed=true installStatus=1
pkgFlags=[ DEBUGGABLE HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
declared permissions:
com.example.permission.test.permissionA: prot=normal, INSTALLED
User 0: installed=true hidden=false stopped=false notLaunched=false enabled=0
runtime permissions:
User 10: installed=true hidden=false stopped=true notLaunched=true enabled=0
runtime permissions:
并运行AppB将捕获异常
12-13 20:59:01.323 4109 4109 E AndroidRuntime: Process: com.example.redfinepermission, PID: 4109
12-13 20:59:01.323 4109 4109 E AndroidRuntime: java.lang.SecurityException: Permission Denial: starting Intent { cmp=com.example.definepermission/.MainActivity } from ProcessRecord{ad97706 4109:com.example.redfinepermission/u0a89} (pid=4109, uid=10089) requires com.example.permission.test.permissionA
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1620)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1573)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2658)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.app.Activity.startActivityForResult(Activity.java:3930)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.app.Activity.startActivityForResult(Activity.java:3890)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.app.Activity.startActivity(Activity.java:4213)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.app.Activity.startActivity(Activity.java:4181)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at com.example.redfinepermission.MainActivity.startNewActivity(MainActivity.java:31)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at com.example.redfinepermission.MainActivity.onClick(MainActivity.java:38)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.view.View.performClick(View.java:5204)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:21153)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
12-13 20:59:01.323 4109 4109 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
如果首先安装AppA,android setting.mPermission将包含com.example.permission.test.permissionA,并安装AppB,android会向AppB授予此正常权限。
此案例可以在google nexus,HW mate8,vivo中重现。 谷歌地图新版首次安装在中国的andorid手机上(仅限中国封印),以及谷歌gms(google play service)leat,这也将重现这个案例。
日志:
Line 36607:12-13 12:23:26.937 2032 3210 D PackageManager:com.google.android.apps.maps perm com.google.android.gms.permission.ACTIVITY_RECOGNITION grant:1 第36609行:12-13 12:23:26.937 2032 3210 W PackageManager:未授予com.google.android.gms.permission.ACTIVITY_RECOGNITION权限以包装com.google.android.apps.maps,因为它之前安装时没有
答案 0 :(得分:2)
android是否授予app同意安装顺序?
是。从几年前引用myself:
Android中的自定义权限是“胜利中的第一个”。换句话说,对于给定
<permission>
,任何应用程序首先具有android:name
元素,都可以为所有后续应用程序定义该权限的详细信息。
答案 1 :(得分:0)
private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
String packageOfInterest) {
...
if (grant != GRANT_DENIED) {
if(DEBUG_PERMISSION){
Slog.d(TAG,"\tps:"+ps+" permissionFix:"+ps.installPermissionsFixed+" origPermissions:"+origPermissions);
}
if (!isSystemApp(ps) && ps.installPermissionsFixed) {
**// If this is an existing, non-system package, then
// we can't add any new permissions to it.** // why ??
if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
if(DEBUG_PERMISSION){
Slog.d(TAG,"\tpkg:"+pkg+" perm:"+perm);
}
// Except... if this is a permission that was added
// to the platform (note: need to only do this when
// updating the platform).
if (!isNewPlatformPermissionForPackage(perm, pkg)) {
grant = GRANT_DENIED;
}
}
}
//add for app lose permission begin
if(grant == GRANT_DENIED){
if(level == PermissionInfo.PROTECTION_NORMAL){
grant = GRANT_INSTALL;
//for normal, just grant.
}else {
allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
if(allowedSig){
//and if signature equal or system app, let get it.
grant = GRANT_INSTALL;
}
}
Slog.i(TAG,"*check signature* level:"+level+" "+pkg.packageName+" perm:"+perm+" grant:"+grant+" allowedSig:"+allowedSig +" bp:"+bp);
}
//add for app lose permission begin
switch (grant) {
case GRANT_INSTALL: {
// Revoke this as runtime permission to handle the case of
// a runtime permission being downgraded to an install one.
for (int userId : UserManagerService.getInstance().getUserIds()) {
if (origPermissions.getRuntimePermissionState(
bp.name, userId) != null) {
// Revoke the runtime permission and clear the flags.
origPermissions.revokeRuntimePermission(bp, userId);
origPermissions.updatePermissionFlags(bp, userId,
PackageManager.MASK_PERMISSION_FLAGS, 0);
// If we revoked a permission permission, we have to write.
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
}
}
这可以解决这个问题,但我想知道为什么?
** //如果这是现有的非系统包,那么 //我们无法为其添加任何新权限。