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

标签 android securityexception android-fileprovider android-securityexception

我有一个应用程序不在 Play 商店中。我之前能够通过以下代码启动应用程序安装程序:

Activity 中:

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,并对我的代码进行了一些更改,但出现以下错误:

FATAL EXCEPTION: AsyncTask #1 Process: com.android.packageinstaller, PID: 6499 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:326) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:244) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) Caused by: java.lang.SecurityException: Permission Denial: opening provider in.namespace.appname.comp.GenericFileProvider from ProcessRecord{ba35e80 6499:com.android.packageinstaller/u0a17} (pid=6499, uid=10017) that is not exported from uid 10076 at android.os.Parcel.readException(Parcel.java:1684) at android.os.Parcel.readException(Parcel.java:1637) at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4213) at android.app.ActivityThread.acquireProvider(ActivityThread.java:5535) at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2239) at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1517) at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1131) at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:984) at android.content.ContentResolver.openInputStream(ContentResolver.java:704) at com.android.packageinstaller.PackageInstallerActivity$StagingAsyncTask.doInBackground(PackageInstallerActivity.java:804) at com.android.packageinstaller.PackageInstallerActivity$StagingAsyncTask.doInBackground(PackageInstallerActivity.java:795) at android.os.AsyncTask$2.call(AsyncTask.java:306) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:244)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)  at java.lang.Thread.run(Thread.java:761) 

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

在 list 中:

<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 { }

将 Activity 代码更改为:

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

更改了我的 list :

<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 并且它导致了问题。所以我从 Intent 中删除了那个标志,它开始工作了。

工作示例代码

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 - SecurityException:打开未从 uid 导出的提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47350278/

相关文章:

android - 在Android上播放声音

Java:在 Applet 中使用 Gson 导致 SecurityException

android - 检查指纹是否已在三星手机中注册时出现 SecurityException

android - Permission Denial : reading androidx. core.content.FileProvider 试图共享视频文件

android - 可以在 Flex Native 扩展中与其他应用程序共享内部文件(例如使用 FileProvider)

c# - resources.designer.cs 不是自动生成的。 (MonoDevelop 初学者)

android - 无法通过 ListView 检测手势

java - 权限拒绝 : opening provider that is not exported from UID 1000

android - 如何使用支持 FileProvider 将内容共享给其他应用程序?

java - Google map 无法使用计时器删除标记