Forget the Storage Permission: Alternatives for sharing and collaborating (Big Android BBQ 2015)

Android Developers · 23K views · 2015 · 45:15

Open on YouTube

Software (other)Software architecture & designtalkdated

Why Stack Overflow recommends it

Stack Overflow users link it when answering questions about sharing files between apps, granting URI permissions, and avoiding storage permissions on Android.

Recommended by 7 people across 7 different months, 2015 to 2023.

What it is

A 45-minute Big Android BBQ 2015 talk by Google developer advocate Ian Lake on avoiding the broad Storage permissions in Android apps. He covers FileProvider, ACTION_GET_CONTENT and the Storage Access Framework as ways to share and collaborate on files across apps.

What people said

Recommends escalant3 · 2015-10 · Stack Overflow · on “Android 6.0 secure intents involving permissions”

I asked the same question in the G+ community and got the same answer. I followed this [this video] I was able to make it work with Hangouts and Gmail. Sadly, as you mention in your post, many apps assume Uri IS a file. I am going to try with a modified provider as suggested. Thanks @CommonsWare!

Recommends ianhanniballake · 2015-11 · Stack Overflow · on “Google Drive PDFViewer is not loading PDF file”

As mentioned in the Forget the Storage Permission Talk [this video] (and slides [LINK] ) and the sharing files training [LINK] , you should not be sending a file URI to other apps as it assumes that other apps have the read storage permission. You should instead use a FileProvider [LINK] to create a URI that all apps can read, with or without the storage permission.

Recommends Aitor Viana · 2015-12 · Stack Overflow · on “How to write external storage "permission denied" in instumentation testing on API 23 or higher”

One thing that comes to my mind is that you're targeting M and maybe not handling the permission request at the runtime. As you say, in M WRITE_EXTERNAL_STORAGE is considered a dangerous permission but, the permission handling also changed. Before M, permissions were declared in the manifest and accepted by the user when installing the app. In M, you also have to request the permissions at runtime. Please check this library that will help you handling the permissions in M. [LINK] I also suggest that you try to avoid external storage whenever possible or even better, storage permissions altogether. Check this fantastic talk from Ian Lake. [this video]

Recommends fattire · 2016-04 · Stack Overflow · on “Can you request permissions synchronously in Android Marshmallow (API 23)'s runtime permissions model?”

So I hate to answer my own question specifically with respect to the android.permission.WRITE_EXTERNAL_STORAGE permission used in my example, but what the heck. For reading and/or writing a file, there is actually a way to completely avoid having to ask for and then check for the permission and thus bypass the whole flow I described above. In this way, the saveFile (Url url, String content) method I gave as an example could continue to work synchronously. The solution, which I believe works in API 19+, eliminates the need for the WRITE_EXTERNAL_STORAGE permission by having a DocumentsProvider act as a "middleman" to basically ask the user on your app's behalf "please select the specific file

Recommends Jonathan Aste · 2016-05 · Stack Overflow · on “Capture image without permission with Android 6.0”

Try this: Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File file = new File(getActivity().getApplicationContext().getExternalFilesDir(android.os.Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + "yourPicture.jpg"); Uri uri = Uri.fromFile(file); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, url); This gives you access to an "external" storage writable for camera apps in this case, but the files are just visible from your app. To learn a little bit more about storage spaces in android see [this video] Hope it helps you!

Recommends Simon · 2016-05 · Stack Overflow · on “Wrong Intent Uri data sharing audio files”

You should check out the official training docs for sharing [LINK] . You should always expect content:// uri's like content://Download/5348 . Because your suppose to call getContentResolver().openInputStream(uri) . So you can just end up using the ShareCompat.IntentReader [LINK] . Other recommended research to watch is: Sharing Content (Android Development Patterns S2 Ep 6) [LINK] Forget the Storage Permission: Alternatives for sharing and collaborating (Big Android BBQ 2015) [this video]

Recommends ianhanniballake · 2017-01 · Stack Overflow · on “Having private pictures in your Android app, which path is correct?”

Per the Forget the Storage Permission talk [this video] , getFilesDir() is indeed the right location for private storage of user data.

Recommends azizbekian · 2017-05 · Stack Overflow · on “Pass several files to another app”

That's achievable with Intent#setClipData(ClipData) [LINK] API. You can see example usage from Ian Lake [LINK] 's talk "Forget the Storage Permission: Alternatives for sharing and collaborating" [this video] talk at Big Android BBQ. [LINK] A slide from the abovementioned talk. An example usage: // Adding into `Intent` ClipData clipData = ClipData.newRawUri(null, contentUri); clipData.addItem(new ClipData.Item(secondContentUri)); intent.setClipData(clipData); // Retrieving from `Intent` ClipData clipData = intent.getClipData(); for (int i = 0, count = clipData.getItemCount(); i < count; ++i) { ClipData.Item item = clipData.getItemAt(i); Uri uri = item.getUri(); }

Cites ianhanniballake · 2015-12 · Stack Overflow · on “Send multiple files of different types via Intent using FileProvider”

As mentioned in the Forget the Storage Permission talk [this video] , FLAG_GRANT_READ_URI_PERMISSION and FLAG_GRANT_WRITE_URI_PERMISSION only apply to the URI set in setData() . If you need multiple Uris, they need to be added as ClipData: ClipData clipData = ClipData.newRawUri(null, imageUri); clipData.addItem(new ClipData.Item(audioUri)); intent.setClipData(clipData); Note that setClipData() [LINK] was only added in API 16.

Cites Ivan · 2016-01 · Stack Overflow · on “Share files via mail app without requesting permission”

I'm getting the file Uri, then use it to build an intent and pass read permissions for that Uri: Intent shareIntent = ShareCompat.IntentBuilder.from(MainActivity.this).setType("image/jpeg") .setStream(uri).getIntent(); String sendTo[] = {"send_to_email@gmail.com"}; shareIntent.putExtra(Intent.EXTRA_EMAIL, to); shareIntent.setData(uri); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); The problem is that shareIntent.setData(uri) adds the Uri as a recipient in the "To" field along with email from sendTo[] . This issue gets fixed by avoiding the shareIntent.setData(uri) , but according to BABBQ talk about file sharing [this video] , the FLAG_GRANT_READ_URI_PERMISSION will not work if the