Using the SAF provided in KitKat, the MediaScanner is not called on files saved to the internal or external storage points of a device. As such I have to determine based on the returned URI if I should attempt to run MediaScanner.
// The SAF uses content URI to pass meta about the file. The following host is used for internal storage.
if (mExportServiceUri.getHost().equals("com.android.externalstorage.documents")) {
final File externalStorage = Environment.getExternalStorageDirectory();
final String path = mExportServiceUri.getEncodedPath().replace("/document/primary%3A", "");
MediaScannerConnection.scanFile(mService.getApplicationContext(), new String[] { new File(
externalStorage, path).getAbsolutePath() }, null, null);
}
Has anyone else had to work around this issue and if so, is there a better approach than this? Currently this only supports the device external storage and additional storage space such as the SDCard need to be handled in a separate check.
To support what I believe to be all possible mounts including USB thumb drives connected via OTG or even possibly directly to the full size usb port on some tablets (I dont have a tablet to test that with, does a 4.4 tablet even exist with a full size port?) I have the following which seems to work well on a Galaxy S4 (Play store edition) and a N5.
// The SAF uses content URI to pass meta about the file. The following host is used for SD storage.
if (mExportServiceUri.getHost().equals("com.android.externalstorage.documents")) {
final String encodedPath = mExportServiceUri.getEncodedPath();
final String path = encodedPath.substring(encodedPath.indexOf("%3A") + 3);
final File[] storagePoints = new File("/storage").listFiles();
// document/primary is in /storage/emulated/legacy and thus will fail the exists check in the else handling loop check
if (encodedPath.startsWith("/document/primary")) {
// External file stored in Environment path
final File externalFile = new File(Environment.getExternalStorageDirectory(), path);
MediaScannerConnection.scanFile(mService.getApplicationContext(),
new String[] { externalFile.getAbsolutePath() }, null, null);
} else {
// External file stored in one of the mount points, check each mount point for the file
for (int i = 0, j = storagePoints.length; i < j; ++i) {
final File externalFile = new File(storagePoints[i], path);
if (externalFile.exists()) {
MediaScannerConnection.scanFile(mService.getApplicationContext(),
new String[] { externalFile.getAbsolutePath() }, null, null);
break;
}
}
}
}