I have some files stored in my internal application store that I would like to open in an external application (for example, sending an image to the gallery for viewing). For this, I created FileProvider .
From AndroidManifest.xml :
<application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="${packageName}" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/files"/> </provider> </application>
From res/xml/files.xml :
<paths> <files-path name="internal_logs" path="logs/"/> <files-path name="shared_files" path="shared/"/> </paths>
From Fragment , where I am trying to open a file:
File sharedFolderPath = new File(getActivity().getFilesDir(), "shared"); File toOpen = new File(sharedFolderPath.getAbsolutePath(), sharedFile.getFileName()); if (toOpen.exists()) { Log.w("File exists: " + toOpen.getAbsolutePath()); Uri fileUri = FileProvider.getUriForFile(getActivity(), BuildConfig.PACKAGE_NAME, toOpen); Log.w("Attempting to attach file " + fileUri.getEncodedPath() + " with mime type: " + URLConnection.guessContentTypeFromName(fileUri.toString())); Intent viewFile = new Intent(Intent.ACTION_VIEW); viewFile.setData(fileUri); viewFile.setType(URLConnection.guessContentTypeFromName(fileUri.toString())); viewFile.putExtra(Intent.EXTRA_STREAM, fileUri); viewFile.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); viewFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); try { startActivity(viewFile); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(getActivity(), "Please install an appropriate application to open this file.", Toast.LENGTH_SHORT).show(); } } else { log.w("File does not exist: " + toOpen.getAbsolutePath()); Toast.makeText(getActivity(), "file not found.", Toast.LENGTH_SHORT).show(); }
From the output of logcat (sharing the Gallery app):
PACKAGE_NAME W/TAG: File exists: /data/data/PACKAGE_NAME/files/shared/IMG_20140506_141221.jpg PACKAGE_NAME W/TAG: Attempting to attach file /shared_files/IMG_20140506_141221.jpg with mime type: image/jpeg 778-791/? I/PackageManager﹕ Action: "android.intent.action.VIEW" 778-791/? I/PackageManager﹕ Category: "android.intent.category.DEFAULT" 778-791/? I/PackageManager﹕ Type: "image/jpeg" 778-791/? I/PackageManager﹕ Adding preferred activity ComponentInfo{com.google.android.gallery3d/com.android.gallery3d.app.GalleryActivity} for user 0 : 778-788/? I/ActivityManager﹕ START u0 {act=android.intent.action.VIEW typ=image/jpeg flg=0x3000001 cmp=com.google.android.gallery3d/com.android.gallery3d.app.GalleryActivity (has extras)} from pid 6209 778-1872/? I/ActivityManager﹕ Start proc com.google.android.gallery3d for activity com.google.android.gallery3d/com.android.gallery3d.app.GalleryActivity: pid=10602 uid=10039 gids={50039, 3003, 1028, 1015} 10602-10602/? V/StateManager﹕ startState class com.android.gallery3d.app.AlbumSetPage
What happens when a file is found, a URI is generated, and the mimetype type is detected correctly; I get an accurate list of Android handlers, and when I select "Gallery", the Gallery action starts, but it goes directly to the device’s own gallery - there is no error message, but there is also no open image. This behavior is similar to other image viewers - for example, G + Photos.
It’s really strange if I execute the same code with the declared ACTION_SEND declaration, the file is correctly attached to the email in Gmail. (In fact, this is what I am doing with the internal logging of my application.) Therefore, it seems unlikely that I formatted the content URI incorrectly. My best guess is that I am using the wrong intent action? But I have no idea what would be better than ACTION_VIEW.
Any ideas?