05/24
2013

google play安装后打开Fc或点击下载时Crash

本文主要介绍google play fc, java.lang.SecurityException: Invalid value for is_public_api: null异常的解决方法及具体原因

 

今天@互联网的那些事转发了三星行货S3手机居然压根儿就不能打开google play商店的问题,会发现很多rom都有这个问题。sansumg fc xiaomi fc那么就顺便介绍下解决的方法吧@三星。

 

1、异常信息:

很多第三方android rom去掉google play后,用户从第三方应用市场下载google play安装后打开Fc或点击下载时Crash
异常信息如下:

Writing exception to parcel
java.lang.SecurityException: Invalid value for is_public_api: null
at com.android.providers.downloads.DownloadProvider.enforceAllowedValues(DownloadProvider.java:942)
at com.android.providers.downloads.DownloadProvider.checkInsertPermissions(DownloadProvider.java:856)
at com.android.providers.downloads.DownloadProvider.insert(DownloadProvider.java:550)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:205)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:148)
at android.os.Binder.execTransact(Binder.java:367)
at dalvik.system.NativeStart.run(Native Method)

FATAL EXCEPTION: main
java.lang.SecurityException: Neither user 10056 nor current process has android.permission.INSTALL_PACKAGES.at android.os.Parcel.readException(Parcel.java:1327)
E/AndroidRuntime(3004):  at android.os.Parcel.readException(Parcel.java:1281)
E/AndroidRuntime(3004):  at android.content.pm.IPackageManager$Stub$Proxy.installPackage(IPackageManager.java:2166)
E/AndroidRuntime(3004):  at android.app.ApplicationPackageManager.installPackage(ApplicationPackageManager.java:974)
E/AndroidRuntime(3004):  at com.google.android.finsky.utils.PackageManagerUtils.installPackage(PackageManagerUtils.java:65)
E/AndroidRuntime(3004):  at com.google.android.finsky.utils.PackageManagerHelper$OnCompleteListenerNotifier.onPostExecute(PackageManagerHelper.java:319)
E/AndroidRuntime(3004):  at com.google.android.finsky.utils.PackageManagerHelper$OnCompleteListenerNotifier.onPostExecute(PackageManagerHelper.java:139)
E/AndroidRuntime(3004):  at android.os.AsyncTask.finish(AsyncTask.java:602)
E/AndroidRuntime(3004):  at android.os.AsyncTask.access$600(AsyncTask.java:156)
E/AndroidRuntime(3004):  at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
E/AndroidRuntime(3004):  at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(3004):  at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(3004):  at android.app.ActivityThread.main(ActivityThread.java:4675)
E/AndroidRuntime(3004):  at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(3004):  at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(3004):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:811)
E/AndroidRuntime(3004):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:578)
E/AndroidRuntime(3004):  at dalvik.system.NativeStart.main(Native Method)

 

2、解决方法:
一种方法是将google play apk从/data/app移到/system/app,这样就是系统应用了,不过现实很多用户不会这种操作且不能让用户这样操作,而应系统自己解决。系统解决方法为修改
frameworks/base/services/java/com/android/server/pm/PackageManagerService.java类的
private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace)函数,
修改如下:

} else if (bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE
		|| bp.protectionLevel == PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
	allowed = (compareSignatures(
			bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
					== PackageManager.SIGNATURE_MATCH)
			|| (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
					== PackageManager.SIGNATURE_MATCH);
	if (!allowed && bp.protectionLevel
			== PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM) {
		if (isSystemApp(pkg)) {
			// For updated system applications, the signatureOrSystem permission
			// is granted only if it had been defined by the original application.
			if (isUpdatedSystemApp(pkg)) {
				final PackageSetting sysPs = mSettings
						.getDisabledSystemPkgLPr(pkg.packageName);
				final GrantedPermissions origGp = sysPs.sharedUser != null
						? sysPs.sharedUser : sysPs;
				if (origGp.grantedPermissions.contains(perm)) {
					allowed = true;
				} else {
					allowed = false;
				}
			} else {
				allowed = true;
			}
		}
	}
// trinea BEGIN
	if (pkg.packageName.equals("com.android.vending") && compareSignatures(pkg.mSignatures, new Signature[]{new Signature("308204433082032ba003020102020900c2e08746644a308d300d06092a
864886f70d01010405003074310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e06035
5040b1307416e64726f69643110300e06035504031307416e64726f6964301e170d3038303832313233313333345a170d3336303130373233313333345a3074310b3009060355040613025553311330110603550408130a43616c69666f726e696131
1630140603550407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f696430820120300d06092a864886f70d0101010
5000382010d00308201080282010100ab562e00d83ba208ae0a966f124e29da11f2ab56d08f58e2cca91303e9b754d372f640a71b1dcb130967624e4656a7776a92193db2e5bfb724a91e77188b0e6a47a43b33d9609b77183145ccdf7b2e586674c9
e1565b1f4c6a5955bff251a63dabf9c55c27222252e875e4f8154a645f897168c0b1bfc612eabf785769bb34aa7984dc7e2ea2764cae8307d8c17154d7ee5f64a51a44a602c249054157dc02cd5f5c0e55fbef8519fbe327f0b1511692c5a06f19d18
385f5c4dbc2d6b93f68cc2979c70e18ab93866b3bd5db8999552a0e3b4c99df58fb918bedc182ba35e003c1b4b10dd244a8ee24fffd333872ab5221985edab0fc0d0b145b6aa192858e79020103a381d93081d6301d0603551d0e04160414c77d8cc2
211756259a7fd382df6be398e4d786a53081a60603551d2304819e30819b8014c77d8cc2211756259a7fd382df6be398e4d786a5a178a4763074310b3009060355040613025553311330110603550408130a43616c69666f726e69613116301406035
50407130d4d6f756e7461696e205669657731143012060355040a130b476f6f676c6520496e632e3110300e060355040b1307416e64726f69643110300e06035504031307416e64726f6964820900c2e08746644a308d300c0603551d130405300301
01ff300d06092a864886f70d010104050003820101006dd252ceef85302c360aaace939bcff2cca904bb5d7a1661f8ae46b2994204d0ff4a68c7ed1a531ec4595a623ce60763b167297a7ae35712c407f208f0cb109429124d7b106219c084ca3eb3f
9ad5fb871ef92269a8be28bf16d44c8d9a08e6cb2f005bb3fe2cb96447e868e731076ad45b33f6009ea19c161e62641aa99271dfd5228c5c587875ddb7f452758d661f6cc0cccb7352e424cc4365c523532f7325137593c4ae341f4db41edda0d0b10
71a7c440f0fe9ea01cb627ca674369d084bd2fd911ff06cdbf2cfa10dc0f893ae35762919048c7efc64c7144178342f70581c9de573af55b390dd7fdb9418631895d5f759f30112687ff621410c069308a")}) == PackageManager.SIGNATURE_MA
TCH){
		allowed = true;
	}
// trinea END

其中// trinea BEGIN和// trinea END为新增部分,表示将包名com.android.vending(google play包名)且签名正确的应用设置为允许,将在后面改变其签名为系统签名当作系统应用处理。

 

3、具体原因:
究其原因是因为第三方rom去掉google play后,用户从市场下载google play后安装并不会当作系统应用处理。
第一个异常原因是非系统应用无法拥有android.permission.ACCESS_DOWNLOAD_MANAGER权限,而在DownloadProvider的insert函数中会调用checkInsertPermissions检查数据库操作权限,代码如下:

private void checkInsertPermissions(ContentValues values) {
	if (getContext().checkCallingOrSelfPermission(Downloads.Impl.PERMISSION_ACCESS)
			== PackageManager.PERMISSION_GRANTED) {
		return;
	}

	getContext().enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
			"INTERNET permission is required to use the download manager");

	// ensure the request fits within the bounds of a public API request
	// first copy so we can remove values
	values = new ContentValues(values);

	// check columns whose values are restricted
	enforceAllowedValues(values, Downloads.Impl.COLUMN_IS_PUBLIC_API, Boolean.TRUE);
	……
}

里面会有一系列的权限认证,上面异常即因为google play的Downloads.Impl.COLUMN_IS_PUBLIC_API为空,不满足为true的条件。

把google play当作系统应用处理后拥有Downloads.Impl.PERMISSION_ACCESS权限,在最开始检查时即满足而退出。

 

第二个异常是因为google play安装程序时使用到了android.permission.INSTALL_PACKAGES权限进行静默安装,而只有系统应用具有该权限。

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

6 thoughts on “google play安装后打开Fc或点击下载时Crash