-
Type: Bug
-
Status: Resolved
-
Priority: Major
-
Resolution: Fixed
-
Affects Version/s: Android 1.0
-
Fix Version/s: Android 1.2
-
Component/s: Android
-
Tags:
-
Sprint:nxfit 9.1.2, nxfit 9.1.3
-
Story Points:5
Downloading a file doesn't work on Android 7.
Trying to open a file with RNFetchBlob.android.actionViewIntent from react-native-fetch-blob we get:
Using the DownloadManager:
12-22 09:17:08.611 5838 7441 D DownloadManager: [186] Finished with status SUCCESS /data/user/0/com.android.providers.downloads/cache/LTS 2015 - Release Notes-4.pdf 12-22 09:17:08.790 4957 9753 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=file:///data/user/0/com.android.providers.downloads/cache/LTS 2015 - Release Notes-4.pdf typ=application/pdf flg=0x10000000 cmp=com.google.android.apps.docs/com.google.android.apps.viewer.PdfViewerActivity} from uid 10102 on display 0 ... 12-22 09:17:10.128 6705 7459 E DisplayData: openFd: java.io.FileNotFoundException: Permission denied 12-22 09:17:10.129 6705 7459 E PdfLoader: Can't load file (doesn't open) Display Data [PDF : LTS 2015 - Release Notes-4.pdf] +FileOpenable, uri: file:///data/user/0/com.android.providers.downloads/cache/LTS 2015 - Release Notes-4.pdf
Downloading directly to the app's internal storage in RNFetchBlob.fs.dirs.DocumentDir (/data/user/0/com.nuxeomobile/files) or RNFetchBlob.fs.dirs.CacheDir (/data/user/0/com.nuxeomobile/cache):
12-22 09:21:03.913 4957 21663 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=file:///data/user/0/com.nuxeomobile/files/ed951904-4f3c-4799-b4bd-37ff558c2913/LTS 2015 - Release Notes.pdf typ=application/pdf flg=0x10000000 cmp=com.google.android.apps.docs/com.google.android.apps.viewer.PdfViewerActivity} from uid 10102 on display 0 ... 12-22 09:21:04.067 6705 6705 E PdfViewerActivity: fetchFile:file: java.io.FileNotFoundException: file does not exist
Yet downloading to external storage works, either in RNFetchBlob.fs.dirs.DCIMDir (/storage/emulated/0/DCIM) of RNFetchBlob.fs.dirs.DownloadDir (/storage/emulated/0/Download):
12-22 09:26:09.094 4957 13074 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=file:///storage/emulated/0/DCIM/ed951904-4f3c-4799-b4bd-37ff558c2913/LTS 2015 - Release Notes.pdf typ=application/pdf flg=0x10000000 cmp=com.google.android.apps.docs/com.google.android.apps.viewer.PdfViewerActivity} from uid 10102 on display 0
We get similar issues when trying to send a file to another application with Share.open form react-native-share:
Using the DownloadManager:
12-22 09:32:22.952 4957 4992 I ActivityManager: START u0 {act=android.intent.action.SEND typ=image/jpeg flg=0xb080001 cmp=com.google.android.apps.messaging/.ui.conversationlist.ShareIntentActivity clip={image/jpeg U:file:///data/user/0/com.android.providers.downloads/cache/Cosmos07-2.jpg} (has extras)} from uid 10102 on display 0 12-22 09:32:23.080 13503 13503 V BugleAction: already have WRITE_EXTERNAL_STORAGE 12-22 09:32:23.093 13503 13503 I Bugle : Could not determine type of file:///data/user/0/com.android.providers.downloads/cache/Cosmos07-2.jpg 12-22 09:32:23.093 13503 13503 I Bugle : java.io.FileNotFoundException: Permission denied
Downloading directly to the app's internal storage in RNFetchBlob.fs.dirs.DocumentDir (/data/user/0/com.nuxeomobile/files) or RNFetchBlob.fs.dirs.CacheDir (/data/user/0/com.nuxeomobile/cache):
12-22 09:34:28.859 4957 7158 I ActivityManager: START u0 {act=android.intent.action.SEND typ=image/jpeg flg=0xb080001 cmp=com.google.android.apps.messaging/.ui.conversationlist.ShareIntentActivity clip={image/jpeg U:file:///data/user/0/com.nuxeomobile/files/26ce5f1b-0f75-4e76-9eb7-b6a90a3e9019/Cosmos07.jpg} (has extras)} from uid 10102 on display 0 12-22 09:34:28.954 13503 13503 V BugleAction: already have WRITE_EXTERNAL_STORAGE 12-22 09:34:28.955 13503 13503 I Bugle : Could not determine type of file:///data/user/0/com.nuxeomobile/files/26ce5f1b-0f75-4e76-9eb7-b6a90a3e9019/Cosmos07.jpg 12-22 09:34:28.955 13503 13503 I Bugle : java.io.FileNotFoundException: Permission denied
Yet downloading to external storage works, either in RNFetchBlob.fs.dirs.DCIMDir (/storage/emulated/0/DCIM) of RNFetchBlob.fs.dirs.DownloadDir (/storage/emulated/0/Download):
12-22 09:44:12.423 4957 9753 I ActivityManager: START u0 {act=android.intent.action.SEND typ=image/jpeg flg=0xb080001 cmp=com.google.android.gm/.ComposeActivityGmailExternal clip={image/jpeg U:file:///storage/emulated/0/DCIM/26ce5f1b-0f75-4e76-9eb7-b6a90a3e9019/Cosmos07.jpg} (has extras)} from uid 10102 on display 0
----------------------------------------------------
We are now following the Android 7.0 Behavior Changes instructions about file sharing using a content:// URI with temporary access permission granted through a FileProvider.
We needed to implement our own RNFileSharing native module for this purpose and also to properly handle the callback for deleting the downloaded file after the Send or View activity has been completed. Indeed:
- RNShareModule#open resolves the promise after having opened the chooser dialog but not after having acually sent the file to the other application.
- RNFetchBlob#actionViewIntent uses a LifecycleEventListener that is working on Android 6 but not on Android 7: the onHostResume method is called right away after having opened the other application, not waiting until it has been closed.
Using ReactContext#startActivityForResult with an ActivityEventListener without setting the Intent#FLAG_ACTIVITY_NEW_TASK on the intent to start solves it.
Note that this also solves: