I try to move image file from my getExternalFilesDir(null) to removable SD card.
I used Storage Access Framework to get my access to SD card.
if (copy(context, sourceUri, targetUri)) return delete(context, sourceUri);
First I copy file to SD card and if it was copied successfully I remove original file from my sandbox.
public static boolean copy(@NonNull Context context, @NonNull Uri sourceUri, @NonNull Uri targetUri) {
InputStream inputStream = openInputStream(context, sourceUri);
OutputStream outputStream = openOutputStream(context, targetUri);
if (inputStream == null || outputStream == null) {
if (inputStream != null) {
try { inputStream.close(); }
catch (IOException ignored) {}
}
if (outputStream != null) {
try { outputStream.close(); }
catch (IOException ignored) {}
}
return false;
}
try {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
I retrieve targetUri by calling this:
Uri targetUri = DocumentsContract.createDocument(context.getContentResolver(), destinationUri, mimeType, filename);
// targetUri is content://com.android.externalstorage.documents/tree/3A3A-11FB%3A/document/3A3A-11FB%3AIMG_2711.gif
File is copied successfully, but this file is never shown nor in Google Photos, nor when I query MediaStore myself. When I reboot device, everything is shown.
This is reproduced not on all devices, but on some, such as Mi A2 Lite on android 9.
I was thinking that content provider is responsible for updating all records for MediaStore. Is there a way to update MediaStore myself?
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE and MediaScannerConnection.scanFile dont work
EDIT: When I try to use getContentResolver().update() I get java.lang.UnsupportedOperationException: Update not supported exception.
I try to update using following code:
final ContentValues vals = new ContentValues();
vals.put(DocumentsContract.Document.COLUMN_DISPLAY_NAME, "testImage.jpg");
context.getContentResolver().update(targetUri, vals , null, null);
Interesting that ContentValues cannot be null, even though they are @Nullable. If they are null following exception will be raised:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.ContentValues.writeToParcel(android.os.Parcel, int)' on a null object reference
at android.content.ContentProviderProxy.update(ContentProviderNative.java:566)
at android.content.ContentResolver.update(ContentResolver.java:1723)
...
context.getContentResolver().refresh(targetUri, null, null); also doesn't seem to do anything.