Search code examples
androidstorage-access-framework

Generating content URI for files in external sdcard or removable storages


Suppose I downloaded a video to /storage/9C33-6BBD/Downloads/video.mp4. How can I open this video from my app? SDK 23+

I tried:

                File file = new File("/storage/9C33-6BBD/Downloads/video.mp4");
                String packageName = context.getApplicationContext().getPackageName();
                Uri uri = FileProvider.getUriForFile(context, myprovider,
                        file);
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                context.startActivity(intent);

But that fails with the following crash. What am I doing wrong?

04-10 02:55:49.889 28144-28144/com.example.one E/AndroidRuntime: FATAL EXCEPTION: main
                                                                  Process: com.example.one, PID: 28144
                                                                  java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/9C33-6BBD/Downloads/video.mp4
                                                                      at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:738)
                                                                      at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:417)
                                                                      at com.example.DownloadAdapter$ViewHolder.onClick(DownloadAdapter.java:385)
                                                                      at android.view.View.performClick(View.java:5612)
                                                                      at android.view.View$PerformClick.run(View.java:22285)
                                                                      at android.os.Handler.handleCallback(Handler.java:751)
                                                                      at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                      at android.os.Looper.loop(Looper.java:154)
                                                                      at android.app.ActivityThread.main(ActivityThread.java:6123)
                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

Solution

  • This is what I ended up doing. A media uri is perfect for my purposes and you can get it via MediaScannerConnection.

                MediaScannerConnection.scanFile(
                        service.getApplicationContext(),
                        new String[] { file.getAbsolutePath() },
                        null,
                        new MediaScannerConnection.OnScanCompletedListener() {
                            @Override
                            public void onScanCompleted(String path, Uri uri) {
                                Log.d(TAG, "file " + path + " was scanned seccessfully: "
                                        + uri);
                                // Do your stuff here. What I did was to do the scan
                                // right after the download and save the uri to my 
                                // database. So I can open this uri later.
                            }
                        });