SecurityException:打开未从uid导出的提供程序



我有一个应用程序不在Play Store上。我早些时候能够通过以下代码启动应用程序安装程序:

活动中:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/app_path/app_name.apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);

现在,我已经将targetSdkVersion更改为25,并对代码进行了一些更改,但我得到了以下错误:

致命异常:异步任务#1进程:com.android.packageinstaller,PID:6499java.lang.RuntimeException:执行doInBackground()时出错在android.os.AsyncTask$3.done(AsyncTask.java:326)位于java.util.concurrent.FFutureTask.finishCompletion(FutureTask.java:354)位于java.util.concurrent.FFutureTask.setException(FutureTask.java:223)位于java.util.concurrent.FFutureTask.run(FutureTask.java:242)在android.os.AsyncTask$SerialExecutor$1.run上(AsyncTask.java:244)位于java.util.concurrent.ThreadPoolExecutiator.runWorker(ThreadPoolExecutiator.java:1133)位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)位于java.lang.Thread.run(Thread.java:761)由以下原因引起:java.lang.SecurityException:拒绝权限:从ProcessRecord{ba35e80 6499.com.android.packageinstaller/u0a17}(pid=6499,uid=10017)打开.namespace.appname.comp.GenericFileProvider中的提供程序,该提供程序不是从uid 10076导出的在android.os.Parcel.readException(Parcel.java:1684)在android.os.Parcel.readException(Parcel.java:1637)位于android.app.ActivityManagerProxy.getContentProvider(ActivityManager Native.java:4213)在android.app.ActivityThread.acquisiteProvider(ActivityThreads.java:5535)在android.app.ContextImpl$ApplicationContentResolver.acquisiteUntableProvider(ContextImpl.java:2239)在android.content.ContentResolver.acquisiteUntableProvider(ContentResolver.java:1517)位于android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1131)位于android.ContentResolver.openAssetFileDescriptor(ContentResolver.java:984)在android.content.ContentResolver.openInputStream(ContentResolver.java:704)网址:com.android.packageinstaller.PackageInstallerActivity$StatiingAsyncTask.doInBackground(PackageInstallerActivity.java:804)网址:com.android.packageinstaller.PackageInstallerActivity$StatiingAsyncTask.doInBackground(PackageInstallerActivity.java:795)在android.os.AsyncTask$2.call上(AsyncTask.java:306)位于java.util.concurrent.FFutureTask.run(FutureTask.java:237)在android.os.AsyncTask$SerialExecutor$1.run上(AsyncTask.java:244)位于java.util.concurrent.ThreadPoolExecutiator.runWorker(ThreadPoolExecutiator.java:1133)位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)在java.lang.Thread.run(Thread.java:761)

这些是我在代码中所做的更改:

在清单中:

<permission
android:name="in.namespace.appname.fp.READ"
android:description="@string/file_provider_permission_description"
android:label="in.namespace.appname.READ_FILE"/>
<uses-permission android:name="in.namespace.appname.fp.READ"/>
<application
...
...
<provider
android:name=".comp.GenericFileProvider"
android:authorities="in.namespace.appname.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
android:readPermission="in.namespace.appname.fp.READ">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
.
.
</application>

在目录comp:中创建一个空类GenericFileProvider

public class GenericFileProvider extends FileProvider { }

将活动代码更改为:

File updatedApk = new File(Environment.getExternalStorageDirectory() + "/file_path/appname.apk");
Uri updatedApkUri =  GenericFileProvider.getUriForFile(
AppUpdateActivity.this,
"in.namespace.appname.fileprovider",
updatedApk);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(updatedApkUri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);

导致此错误的原因是什么?我如何修复此错误?

编辑#1

更改了我的清单:

<provider
android:name=".comp.GenericFileProvider"
android:authorities="in.namespace.appname.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>

在我的情况下,启动Intent有这个标志Intent.FLAG_ACTIVITY_NEW_TASK,它导致了问题。所以我从意图中删除了那个标志,它开始工作了。

工作样本代码

String myPackageName = getApplicationContext().getPackageName();
File f = new File(Environment.getExternalStorageDirectory() + "/Download/" + downloadName);
Uri mediaUri = FileProvider.getUriForFile(getApplicationContext(), myPackageName + ".provider", f);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(mediaUri, "application/vnd.android.package-archive");
startActivity(intent);

删除android:readPermission="in.namespace.appname.fp.READ"

Uri updatedApkUri =  GenericFileProvider.getUriForFile(
AppUpdateActivity.this,
"in.namespace.appname.fileprovider",
updatedApk);

请将您的代码更改为此

Uri updatedApkUri =  GenericFileProvider.getUriForFile(
AppUpdateActivity.this,
BuildConfig.APPLICATION_ID + ".provider",
updatedApk);

并像这个一样管理权限

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
} else if (Build.VERSION.SDK_INT >= 
Build.VERSION_CODES.JELLY_BEAN) {
val clip = ClipData.newUri(contentResolver, "A photo", 
mImageCaptureUri)
intent.clipData = clip
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
} else {
val resInfoList = 
packageManager.queryIntentActivities(intent, 
PackageManager.MATCH_DEFAULT_ONLY)
for (resolveInfo in resInfoList) {
val packageName = 
resolveInfo.activityInfo.packageName
grantUriPermission(packageName, mImageCaptureUri, 
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or 
Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
}
}
intent.putExtra("return-data", true)

相关内容

  • 没有找到相关文章

最新更新