I am trying to download a text file to MediaStore.Downloads (to support scoped storage in Android R) and then read the contents of that file.
I was initially using the DownloadManager to download the file to Environment.DIRECTORY_DOWNLOADS and then use a ContentResolver query to find the content:// Uri through MediaStore.Downloads. But I found the file was often not immediately available through the MediaStore (although it would appear at some point in the future).
So I moved on to using a JobIntentService to download the file using OkHttp to MediaStore.Downloads, e.g.
ContentResolver resolver = getApplicationContext().getContentResolver();
Uri downloads = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
// Originally using MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
ContentValues fileContent = new ContentValues();
fileContent.put(MediaStore.Downloads.DISPLAY_NAME, file.name());
fileContent.put(MediaStore.Downloads.SIZE, fileSize);
fileContent.put(MediaStore.Downloads.IS_PENDING, 1);
Uri downloadedFileUri = resolver.insert(downloads, fileContent); // Save this Uri for later access
try (InputStream inputStream = response.body().byteStream();
OutputStream outputStream = resolver.openOutputStream(downloadedFileUri)) {
// ... Download and write the file ...
}
fileContent.put(MediaStore.Downloads.IS_PENDING, 0);
resolver.update(downloadedFileUri, fileContent, null, null);
I then pass the saved Uri downloadedFileUri to another class that loads the file using an input stream, e.g.
try (InputStream inputStream = resolver.openInputStream(downloadedFileUri)) {
Log.d(TAG, "Input stream size has " + inputStream.available() + " bytes available"); // This returns 0
// ... read the file using a BufferedReader ...
}
But the InputStream contains no data. I've created a ContentResolver query to MediaStore.Downloads to confirm that the file is in the MediaStore:
try (Cursor cursor = resolver.query(MediaStore.Downloads.EXTERNAL_CONTENT_URI,
projection, null, null, idSortOrder)) {
Log.i(TAG, DatabaseUtils.dumpCursorToString(cursor)); // I can see the file in the cursor dump here
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Downloads._ID));
Uri uri = ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI, id);
if (downloadedFileUri.equals(uri)) {
Log.d(TAG, "Uri from cursor matches params, Uri: " + uri); // Getting a match here
}
}
}
I can also find the downloaded file through the Files browser and confirm that the file is not empty. So why does the InputStream not return any data?