Vojtěch Hořánek Vojtěch Hořánek - 28 days ago 27
Android Question

Open downloaded file on Android Nougat with File provider

Hi stackoverflow im having really hard time opening downloaded apk on Android Nougat. I know file provider needs to be used by i just cant figure out how to enter the correct path. The app either crashes or the file is not found. It always opens /storage/emulated/0/Android/data/cf.vojtechh.apkmirror/Downloads - Which of course doesnt exists. I need the app to acces the Download directory in Internal Storage(something like Environment.getExternalStorageDirectory().getPath() + "/" + Environment.DIRECTORY_DOWNLOADS + "/" + fileName)

Any ideas? I've been looking for this all over the internet for over an hour but I just can't find it(I got to that point that i was so angry that i wanted to leave the crash there and ignore it)

MainActivity.java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
File apkfile = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), fileName);
Uri apkUri = FileProvider.getUriForFile(MainActivity.this, "cf.vojtechh.apkmirror.provider", apkfile);
String s = apkUri.toString();
Log.d("HERE!!",s);
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);

} else {
File apkfile = new File(Environment.getExternalStorageDirectory().getPath() + "/" + Environment.DIRECTORY_DOWNLOADS + "/" + fileName);
Uri apkUri = Uri.fromFile(apkfile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}


provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="Download" path="Download/"/>
</paths>


AndroidManifest.xml

<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="cf.vojtechh.apkmirror.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>

Answer

Try using the Environment#getExternalStoragePublicDirectory() method instead. Context#getExternalFilesDir() is meant to be used for files private to your app, hence the path containing your app's package name (technically this directory is public, but still not what you are looking for).

File downloads = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

Then you can create a File representation of the downloaded file:

File apk = new File(downloads, filename);