Can't read thumbnails on Android 10 (loadThumbnail)
Asked Answered
B

3

10

I'm reading thumbnails from the device by querying the MediaStore, using MediaStore.Images.Thumbnails.getThumbnail(). However, this has been deprecated in Android 10 (API 29), with a pointer to ContentResolver#loadThumbnail: https://developer.android.com/reference/android/provider/MediaStore.Images.Thumbnails

However, I can't get this to work (in an emulated device running API 29). I've copied some JPEGs onto the emulated device, which end up in the Downloads folder. They show up fine in the Photos app. The following code gives me a FileNotFoundException. What does "No content provider" actually tell me?

try {

    Size thumbSize = new Size(100, 100);
    Uri thumbUri = Uri.fromFile(new File(imgPath));
    // imgPath: /storage/emulated/0/Download/pexels-photo-323490.jpeg
    // thumbUri: file:///storage/emulated/0/Download/pexels-photo-323490.jpeg

    Bitmap thumbBitmap;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        thumbBitmap = mContext.getContentResolver().loadThumbnail(thumbUri, thumbSize, null);
    } else {
        thumbBitmap = MediaStore.Images.Thumbnails.getThumbnail(mContext.getContentResolver(),
                imgId, MediaStore.Images.Thumbnails.MINI_KIND, null);
    }

    iconView.setImageBitmap(thumbBitmap);
} catch (Exception e) {
    Log.e("err", e.toString());
}

Exception:

java.io.FileNotFoundException: No content provider: file:///storage/emulated/0/Download/pexels-photo-323490.jpeg
Bonnett answered 20/2, 2020 at 11:18 Comment(10)
have you created a content provider? developer.android.com/guide/topics/providers/…Meridithmeriel
Yes, I have a ContentProvider which interfaces the MediaStore: public class PhotoProvider extends ContentProvider. My query method returns a cursor which contains, among other fields, the thumbnail "data" (i.e. path): String thumbData = cursor.getString(PhotoFragment.COL_THUMB_DATA);Bonnett
The pasted code is from my RecyclerViewCursorAdapter class, which binds a row from the cursor to a view element in a RecyclerView (grid).Bonnett
... so I was thinking that my Content Provider sort of had done its job at this point. It has retrieved the data from the MediaStore -- including the path -- and the adapter class should just display it in the UI. But I understand that bitmaps do require a certain amount of extra work :)Bonnett
Is it really asking for my content provider?Bonnett
file:///storage/emulated/0/Download/pexels-photo-323490.jpeg If you use an uri like that then no content provider is involved. And not yours either. Function .loadThumbnail() will never work with such an uri.Photon
Thanks for replying! But you see the scenario here: I'm getting all images from the MediaStore. What, then, is the proper way to load the thumbnails as bitmaps into the UI? The uri, by the way, is what I get from the recommended fromFile method...Bonnett
Getting all the metadata, that is.Bonnett
Could you perhaps clarify how to get a usable uri from querying the MediaStore?Bonnett
Please try this, hope it works for You int thumbColumn = cur.getColumnIndexOrThrow(MediaStore.Images.ImageColumns._ID); int _thumpId = cur.getInt(thumbColumn); Uri imageUri_t = imageUri_t = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,_thumpId);Mcneill
M
6

Please try this, hope it works for You:

int thumbColumn = cur.getColumnIndexOrThrow(MediaStore.Images.ImageColumns._ID); 
int _thumpId = cur.getInt(thumbColumn); 
Uri imageUri_t = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,_thumpId);

GGK

Mcneill answered 20/2, 2020 at 22:19 Comment(3)
Thanks, @GGK! I now get a usable uri, of type content://media/external/images/media/31Bonnett
How come I failed to use this Uri for the loadThumbnail function for getting album art of mp3 files using the query Uri of MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL) ? It keeps getting me FileNotFoundException (and I have the storage permission granted)... Can you please post full sample code for this? Or maybe this is all intended only for image files?Stow
Thats while album arts are embedded in mp3 audio files. You have to use uri = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL); instead of and fetch the album art using MediaMetadataRetrieverMcneill
B
1

The best Answer for getting Thumbnail and All Android Versions is this:

val thumbnail: Bitmap = if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)) {
    mContentResolver.loadThumbnail(contentUri, Size(width / 2, height / 2), null)
} else {
    MediaStore.Images.Thumbnails.getThumbnail(mContentResolver, id, MediaStore.Images.Thumbnails.MINI_KIND, null)
}
Bowles answered 15/6, 2021 at 1:34 Comment(1)
This is the same thing that was posted in the question. It does not address the issue in any wayMasjid
C
0

The uri may not be good. I mean try using FileProvider to get uri of the file. If your legecyExternalStorage is false, then you can not access file like this. The same goes for android 12. You need to use MediaStore to get the contentUri

Cornie answered 29/12, 2021 at 7:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.