Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ALBUM_ART column is deprecated from API 29 and so on, how to obtain path?

We are currently obtaining the path of album art using: MediaStore.Audio.AlbumColumns.ALBUM_ART, and is successfully obtaining the path, except on pixel 3a (Android 10). After some research, the ALBUM_ART became deprecated API 29 and over as shown: Here

In this link it says: "Apps may not have file system permissions to directly access this path. Instead of trying to open this path directly, apps should use ContentResolver#loadThumbnail to gain access."

My questions are:
1) I'm already stating on the application manifest the permissions for external storage access (READ_EXTERNAL_STORAGE) and is requesting permission while navigating in-app. Which permissions do i have to provide to allow access to album art in order to obtain the path?

2) I can't seem to find any content on loadThumbnail online (and not even on ContentResolver class through code, while i am using target and compile SDK 29), if 1) can't be done, then how do i use loadThumbnail and why it's not showing on code?

Thanks in advance.

like image 489
Serge Avatar asked Sep 20 '19 14:09

Serge


3 Answers

In order to use the method of ContentResolver, make sure you have the latest SDK and relevant tools installed, and in your code first instantiate a ContentResolver object and then use it accordingly:

public class MainActivity extends AppCompatActivity {
    public ContentResolver resolver;
    Bitmap albumArt;
    Size size;
    Uri uriOfItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        resolver = new ContentResolver(this) {
            @NonNull
            @Override
            public Bitmap loadThumbnail(@NonNull Uri uri, @NonNull Size size, @Nullable CancellationSignal signal) throws IOException {
                return super.loadThumbnail(uri, size, signal);
            }
        };
        //uriOfItem = uri of your file
        size = new Size(100, 100);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            try {
                albumArt = resolver.loadThumbnail(uriOfItem, size, null);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

EDIT: when it comes to your first question if @Rj_Innocent_Coder doesn't mind me including his comment here:

As part of the scoped-storage feature on Android Q, Google announced that SAF (storage access framework) will replace the normal storage permissions. This means that even if you will try to use storage permissions, it will only grant to access to specific types of files for File and file-path to be used

EDIT 2: after @hetoan2 's comment I check the documentation again and I noticed that ContentResolver is abstract hence not being able to use ContentResolver.loadThumbnail() as a method call. That means that within an activity you could simply use the following as well:

Bitmap albumArt = getContentResolver().loadThumbnail(uriOfFile, sizeOfAreaThatDisplaysThumbnail, cancellationSignalOrNull);
like image 69
Nikos Hidalgo Avatar answered Oct 12 '22 18:10

Nikos Hidalgo


For someone else who is having issues here, this is the solution that worked for me:

if(android.os.Build.VERSION.SDK_INT >= 29)
{
    val album = "Name Of Album"
    val artist = "Name of Artist"
    // Determine album ID first
    val cursor = context.contentResolver.query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
                MediaStore.Audio.Albums.ALBUM_ID,
                "${MediaStore.Audio.Albums.ALBUM} = '$album' AND 
                 ${MediaStore.Audio.Albums.ARTIST} = '$artist'"
                 ,null,null)
    val uri = if(cursor != null && cursor.count > 0)
    {
        cursor.moveToFirst()
        ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, cursor.getString(0).toLong())
    }
    else
    {
        // Dummy URI that will not return an image
        // If you end up here, the album is not in the DataStore
        MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI
    }
    val bm = try
    {
        // Set size based on size of bitmap you want returned
        context.contentResolver.loadThumbnail(uri, Size(50,50), null)
    }
    catch(e: java.lang.Exception)
    {
        // Return default image indicating no image available from DataStore
        BitmapFactory.decodeResource(context.resources, R.drawable.no_image)
    }
}
like image 24
Rob Avatar answered Oct 12 '22 18:10

Rob


try this it will work and load with glide imageView

int thumbColumn = audioCursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns._ID);
   int _thumpId = audioCursor.getInt(thumbColumn);
   imgFilePath = "content://media/external/audio/albumart/"+_thumpId;  
   audioCursor.moveToPosition(i);
  Glide.with(getContext()).load(imgFilePath).placeholder(R.drawable.missed).into(tracksAlbumArt);

Update Andriod Studio latest 4.2.X and targetSdkVersion to 30

like image 1
satishprattipati Avatar answered Oct 12 '22 18:10

satishprattipati