Empty InputStream for file downloaded to MediaStore.Downloads

Viewed 2003

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?

0 Answers
Related