0

I know this is a SecurityException issue but I just don't know how to solve it.

In my code I want to launch android installer for a downloaded apk file which is saved in download folder in external storage directory.

I have this code:

String fileName = "my_file_name.apk";
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                    + "/" + fileName);
Intent i = new Intent(Intent.ACTION_VIEW);
Uri uri;
if (Build.VERSION.SDK_INT < 24) {
     uri = Uri.fromFile(file);
} else { //>=24
     uri = FileProvider.getUriForFile(
                        context,
                        context.getApplicationContext()
                                .getPackageName() + ".provider", file);
}
i.setDataAndType(uri, "application/vnd.android.package-archive");
i.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.getApplicationContext().startActivity(i);

This code runs perfectly at sdk < 24, but at sdk 24 (android 7) and higher, I get the following exception:

Process: com.google.android.packageinstaller, PID: 22774
                                               java.lang.RuntimeException: An error occurred while executing doInBackground()
  at android.os.AsyncTask$3.done(AsyncTask.java:318)
  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:243)
  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:762)
Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{f9741d3 22774:com.google.android.packageinstaller/u0a28} (pid=22774, uid=10028) that is not exported from uid 10186
  at android.os.Parcel.readException(Parcel.java:1693)
  at android.os.Parcel.readException(Parcel.java:1646)
  at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4912)
  at android.app.ActivityThread.acquireProvider(ActivityThread.java:6043)
  at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2474)
  at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1521)
  at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1135)
  at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:988)
  at android.content.ContentResolver.openInputStream(ContentResolver.java:708)
  at com.android.packageinstaller.PackageInstallerActivity$StagingAsyncTask.doInBackground(PackageInstallerActivity.java:792)
  at com.android.packageinstaller.PackageInstallerActivity$StagingAsyncTask.doInBackground(PackageInstallerActivity.java:783)
  at android.os.AsyncTask$2.call(AsyncTask.java:304)
  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
  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:762) 

Is there a run-time permission that I have to ask the user for?

Jayden
  • 13
  • 5
  • Does this answer your question? [Android - file provider - permission denial](https://stackoverflow.com/questions/24467696/android-file-provider-permission-denial) – Sam Jul 26 '22 at 23:42

1 Answers1

3

Add FLAG_GRANT_READ_URI_PERMISSION to the Intent. Right now, the installer app has no rights to access your content.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • It solved my issue. But I'm asking myself why should that file be my content while it is a file in download folder in a public directory? – Jayden Mar 11 '18 at 06:43
  • @Jayden: "But I'm asking myself why should that file be my content while it is a file in download folder in a public directory?" -- you are not using `ACTION_VIEW` on a file. You are using `ACTION_VIEW` on a piece of content served by a `ContentProvider`. By default, other apps do not have access to content served by a `ContentProvider` -- you need to grant access as appropriate, such as via `FLAG_GRANT_READ_URI_PERMISSION`. – CommonsWare Mar 11 '18 at 11:51