2

I am making an application that downloads files from the internet and allows the user to open these files using third party applications. I store these files in my private application directory using getFilesDir().

However, seems like these files can't be accessed by third party apps because when I try to open them (using a 3rd-party app chooser like this one), it is unable to open the file. Is there a permission I need to enable to share my files with other apps?

EDIT: it seems like to use a File Provider, you need to specify the package name of the 3rd-party-app for which you want to provide access to. Is this correct, or is there a workaround to provide general 3rd-party-access?

Community
  • 1
  • 1
woojoo666
  • 7,801
  • 7
  • 45
  • 57

2 Answers2

2

You have two options.

Register the app as a FileProvider

You have a complete and updated example in the Android documentation: https://developer.android.com/reference/android/support/v4/content/FileProvider.html

If you want to provide access to any 3rd party app, you can use this workaround:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
(...)
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

Save the files in the mass storage unit (sdcard)

For example:

File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/newDir");
dir.mkdirs();
File file = new File(dir, "filename");

FileOutputStream f = new FileOutputStream(file);
...

Which one to choose

It depends on your goal.

If you want the user to have access to the files via usb, to make them available even after your app has been uninstalled, to not have the "used space" count of those files added to you app,... The "mass storage unit way" is the way to go.

If you want those files to be "tied" to your app, only available while your app is installed, only accesible via you app,... the "FileProvider way" is the way to go.

In Android, "mass storage unit way" seems preferible if it is not sensible data. Android people don't like "chains"/restrictions.

Mikel Pascual
  • 2,202
  • 18
  • 27
  • Thanks, I opted to use the SD card, using `Context.getExternalDir(null)` to get the application public storage. Just out of curiosity, how does your workaround work? – woojoo666 Jul 19 '14 at 02:18
  • 1
    The workaround is based on: searching for a list of applications which can handle an intent, and then granting permission to all of them (one by one). It's not very beautiful (Android should probably have this integrated already), but gets the job done. – Mikel Pascual Jul 19 '14 at 03:03
  • access denied to create a directory. Though I have granted **READ_EXTERNAL_STORAGE** permission. And as per android [doc](https://developer.android.com/guide/topics/manifest/uses-permission-element), we don't required **WRITE_EXTERNAL_STORAGE** permission in sdk version >=19. So how how to store a file in public directory that can accesable from any other third party app in that device? – Prantik Mondal Aug 25 '21 at 13:23
1

The recommended way of doing in this case would be for your app to act as a FileProvider, granting temporary access to your files to third party applications.

Alternatively, you could use the DownloadManager component to download your files and persist them on a specific location on the device. In the case the files you want to download aren't private to your app, and you would like to make them permanently accessible to third party components, use the download manager to trigger media scanning on the downloaded files, this will make them available through the MediaStore to other apps.

Using the DownloadManager provides some advantages over having to handle the download of the files yourself, and integrates in a more natural way in terms of user experience.

Halim Qarroum
  • 13,985
  • 4
  • 46
  • 71