[TIMOB-28059] Android: Modify Ti.Media APIs to use scoped storage
| GitHub Issue | n/a | 
|---|---|
| Type | Improvement | 
| Priority | High | 
| Status | Closed | 
| Resolution | Fixed | 
| Resolution Date | 2020-10-22T22:19:42.000+0000 | 
| Affected Version/s | n/a | 
| Fix Version/s | Release 9.3.0 | 
| Components | Android | 
| Labels | android, camera, media, photo, storage, video | 
| Reporter | Joshua Quick | 
| Assignee | Joshua Quick | 
| Created | 2020-07-30T04:52:40.000+0000 | 
| Updated | 2020-10-22T22:19:42.000+0000 | 
Description
	*Summary:*
The following APIs can write to file outside of the app's sandbox on external storage and need to be changed for Android 11.
* )) on Android 11.
 
Ti.Media.showCamera()
* Ti.Media.saveToPhotoGallery()
*To-Do:*
Remove usage of the following Java APIs for Android 10 and above...
* [Environment.getExternalStorageDirectory()](https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory())
* [Environment.getExternalStoragePublicDirectory()](https://developer.android.com/reference/android/os/Environment#getExternalStoragePublicDirectory(java.lang.String))
When using an external camera app, it would be better to let it save the photo to its default location and then use a Java ContentResolver to access the photo's InputStream.
https://developer.android.com/training/camera/photobasics
For saving a photo to the gallery...
* Use [ContentResolver.openOutputStream()](https://developer.android.com/reference/android/content/ContentResolver#openOutputStream(android.net.Uri)) on Android 10.
* Use [MediaStore.createWriteRequest()](https://developer.android.com/reference/android/provider/MediaStore#createWriteRequest(android.content.ContentResolver,%20java.util.CollectionAttachments
| File | Date | Size | 
|---|---|---|
| CameraPhotoExternalTest.js | 2020-10-01T21:28:49.000+0000 | 984 | 
| CameraPhotoInternalTest.js | 2020-10-01T22:08:02.000+0000 | 1465 | 
| CameraVideoExternalTest.js | 2020-10-01T21:28:49.000+0000 | 1095 | 
| CameraVideoInternalTest.js | 2020-10-01T22:08:02.000+0000 | 1841 | 
| ImageToGalleryTest.js | 2020-10-10T04:36:37.000+0000 | 870 | 
| Screenshot_1602166786.png | 2020-10-08T14:23:40.000+0000 | 67687 | 
PR (master): https://github.com/appcelerator/titanium_mobile/pull/12143
[~jquick] I carried out some extensive testing of this PR and can confirm the fixes are mostly okay. However, on this particular section of this PR, saved images/screenshots to the photo gallery are not seen unless restarting the emulator (Android 4.4 - 9.0). No restart is required for Android 10/11. This message appears for Android versions < 10. But the screenshot is actually present in the gallery if the emulator is restarted. !Screenshot_1602166786.png|thumbnail!
[~ssaddique], you're right. On Android 6 to Android 9, it will fail to save to the gallery if the app was not granted
WRITE_EXTERNAL_STORAGEpermission. This permission is only not needed on Android 10 and higher. On Android 4.4, there is a bug on Google's end (link below) where it will fail if you've never saved a photo/video on the device before. It's happening because the photo directory doesn't exist. I can only reproduce it by formatting external storage (aka: the SD card). I can fix this issue in Titanium by creating the directory tree if missing. https://issuetracker.google.com/issues/37002888 I'll try to get this PR fixed by your Monday. Thanks![~ssaddique], the PR has been updated. Can you re-run all of the tests on the PR please? I've also updated the attached [^ImageToGalleryTest.js] script to use the
Ti.Media.requestPhotoGalleryPermissions()method on Android, which was newly added to that PR and covers ticket [TIMOB-28183].Fixes look good. FR passed and PR merged.
Verified the fix with SDK 9.3.0.v20201022111908. Closing.