I am working on a function to download an image from a web server, display it on the screen, and if the user wishes to keep the image, save it on the SD card in a certain fo
After Android 4.4 Kitkat, and as of 2017 share of Android 4.4 and less is about 20% and decreasing, it's not possible to save to SD card using File
class and getExternalStorageDirectory()
method. This method returns your device internal memory and images save visible to every app. You can also save images only private to your app and to be deleted when user deletes your app with openFileOutput()
method.
Starting with Android 6.0, you can format your SD card as an internal memory but only private to your device.(If you format SD car as internal memory, only your device can access or see it's contents) You can save to that SD card using other answers but if you want to use a removable SD card you should read my answer below.
You should use Storage Access Framework to get uri to folder onActivityResult
method of activity to get folder selected by user, and add retreive persistiable permission to be able to access folder after user restarts the device.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
// selectDirectory() invoked
if (requestCode == REQUEST_FOLDER_ACCESS) {
if (data.getData() != null) {
Uri treeUri = data.getData();
tvSAF.setText("Dir: " + data.getData().toString());
currentFolder = treeUri.toString();
saveCurrentFolderToPrefs();
// grantUriPermission(getPackageName(), treeUri,
// Intent.FLAG_GRANT_READ_URI_PERMISSION |
// Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(treeUri, takeFlags);
}
}
}
}
Now, save save folder to shared preferences not to ask user to select folder every time you want to save an image.
You should use DocumentFile
class to save your image, not File
or ParcelFileDescriptor
, for more info you can check this thread for saving image to SD card with compress(CompressFormat.JPEG, 100, out);
method and DocumentFile
classes.