FileShuttleService: trigger media scanner after writes as well
Previously, we have been triggering the media scanner after calls to `createFile()`. This is not robust, though, as in many cases the writer is not able to finish writing (i.e. *actually* creating the file) before the scanner is scheduled, resulting in media copied into the work profile not showing up in galleries etc. Turns out, ParcelFileDescriptor supports a `listener` argument in its `open()` calls. This listener is triggered when the fd is actually closed by the (potentially remote) writer. To have robust media scanning, we simply re-trigger the scanner every time a writable ParcelFileDescriptor is closed.
This commit is contained in:
parent
20369aafd2
commit
584bd25aeb
|
@ -101,10 +101,24 @@ public class FileShuttleService extends Service {
|
||||||
public ParcelFileDescriptor openFile(String path, String mode) {
|
public ParcelFileDescriptor openFile(String path, String mode) {
|
||||||
resetSuicideTask();
|
resetSuicideTask();
|
||||||
File f = new File(resolvePath(path));
|
File f = new File(resolvePath(path));
|
||||||
|
int numericMode = ParcelFileDescriptor.parseMode(mode);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return ParcelFileDescriptor.open(f, ParcelFileDescriptor.parseMode(mode));
|
if ((numericMode & ParcelFileDescriptor.MODE_WRITE_ONLY) != 0) {
|
||||||
} catch (FileNotFoundException e) {
|
// When the file is opened in writable mode, and the file is of a media
|
||||||
|
// type, we need to notify the media scanner of the update.
|
||||||
|
// Even though this is done as part of file creation as well, that scan
|
||||||
|
// might have failed because it happened before the writer was able to
|
||||||
|
// finish writing.
|
||||||
|
return ParcelFileDescriptor.open(f, numericMode, mHandler, (e) -> {
|
||||||
|
String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
|
||||||
|
Utility.getFileExtension(f.getAbsolutePath()));
|
||||||
|
notifyMediaScannerIfNecessary(f, mime);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return ParcelFileDescriptor.open(f, numericMode);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,8 +152,6 @@ public class FileShuttleService extends Service {
|
||||||
DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType);
|
DocumentsContract.Document.MIME_TYPE_DIR.equals(mimeType);
|
||||||
boolean shouldAppendExtension =
|
boolean shouldAppendExtension =
|
||||||
mimeType != null && !isDirectory && !mimeType.equals("application/octet-stream");
|
mimeType != null && !isDirectory && !mimeType.equals("application/octet-stream");
|
||||||
boolean isMedia =
|
|
||||||
mimeType != null && (mimeType.startsWith("image/") || mimeType.startsWith("video/"));
|
|
||||||
|
|
||||||
// Append extension for files if a MIME type is specified
|
// Append extension for files if a MIME type is specified
|
||||||
if (shouldAppendExtension) {
|
if (shouldAppendExtension) {
|
||||||
|
@ -159,13 +171,7 @@ public class FileShuttleService extends Service {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the media scanner to scan the file as needed
|
notifyMediaScannerIfNecessary(f, mimeType);
|
||||||
// This has to be done AFTER file creation
|
|
||||||
if (isMedia) {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
|
||||||
intent.setData(Uri.fromFile(f));
|
|
||||||
sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return f.getAbsolutePath();
|
return f.getAbsolutePath();
|
||||||
}
|
}
|
||||||
|
@ -299,4 +305,14 @@ public class FileShuttleService extends Service {
|
||||||
|
|
||||||
return pair[0];
|
return pair[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void notifyMediaScannerIfNecessary(File f, String mimeType) {
|
||||||
|
// Notify the media scanner to scan the file as needed
|
||||||
|
// This has to be done AFTER file creation
|
||||||
|
if (mimeType != null && (mimeType.startsWith("image/") || mimeType.startsWith("video/"))) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
||||||
|
intent.setData(Uri.fromFile(f));
|
||||||
|
sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue