cover art on android - android

I am developing a sort of media player for android. The question is how can i get the cover art of audio file on android.
For example the default android media player shows album covers when listing albums, how can i get this artworks.

Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
ContentResolver res = context.getContentResolver();
InputStream in = res.openInputStream(uri);
Bitmap artwork = BitmapFactory.decodeStream(in);
More complete sample code can be found in Android Music player source here https://github.com/android/platform_packages_apps_music/blob/master/src/com/android/music/MusicUtils.java method getArtworkQuick.

You can use
MediaMetadataRetriever
class and get track info i.e. Title,Artist,Album,Image
Bitmap GetImage(String filepath) //filepath is path of music file
{
Bitmap image;
MediaMetadataRetriever mData=new MediaMetadataRetriever();
mData.setDataSource(filePath);
try{
byte art[]=mData.getEmbeddedPicture();
image=BitmapFactory.decodeByteArray(art, 0, art.length);
}
catch(Exception e)
{
image=null;
}
return image;
}

I don't know why everybody is making it so complicated you can use Glide to achieve this in simplest and efficient way with just 1 line of code
Declare this path in App Constants -
final public static Uri sArtworkUri = Uri
.parse("content://media/external/audio/albumart");
Get Image Uri using Album ID
Uri uri = ContentUris.withAppendedId(PlayerConstants.sArtworkUri,
listOfAlbums.get(position).getAlbumID());
Now simply display album art using uri :-
Glide.with(context).load(uri).placeholder(R.drawable.art_default).error(R.drawable.art_default)
.crossFade().centerCrop().into(holder.albumImage);
Glide will handle caching, scaling and lazy loading of images for you.
Hope it help somebody.

Here i can attach one function that is return album art from media store .
Here in function we just have to pass the album_id which we get from Media store .
public Bitmap getAlbumart(Long album_id)
{
Bitmap bm = null;
try
{
final Uri sArtworkUri = Uri
.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null)
{
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd);
}
} catch (Exception e) {
}
return bm;
}

Based on your comments to others, it seems like your question is less about Android and more about how to get album art in general. Perhaps this article on retrieving album art from Amazon will be helpful. Once you have a local copy and store it as Nick has suggested, I believe you should be able to retrieve it the way Fudgey suggested.

Android only recognizes files named "AlbumArt.jpg" as Album Covers. Just put the pictures with that name in the album folder and you'll be fine..

I don't know if you read that google is making Stackoverflow the official Android app development Q&A medium but for beginner questions... Now, I know nothing about developing in andriod, but a quick search of the Android Developers site, I found this:
MediaStore.Audio.AlbumColumns
Hopefully it'll help.

Related

Is there any way to create Uri from bitmap but i don't want to see it in image gallery?

Scenario: I am using MessagingStyle notification in a chat application. For image messages, I am using setData function to create image notification in conversation style.
public Message setData(String dataMimeType, Uri dataUri)
This method required dataUri but I have URL of image so I have created a bitmap from image url and then create a uri from batmap using function below.
public static Uri getImageUri(Context applicationContext, Bitmap photo) {
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(applicationContext.getContentResolver(), photo, "IMG_" + Calendar.getInstance().getTime(), null);
if (path == null) {
return null;
}
return Uri.parse(path);
} catch (SecurityException ex) {
ex.printStackTrace();
return null;
}
}
Problem: Now the problem is that when user open image gallery, these notifications images are showing because I used mediastore to create URI. I don’t want these image to show in gallery.
Limitation: I am also saving that URI in case If I have to generate this notification again. So I can’t delete that image immediately to avoid showing in gallery.
Question: Is there any way to save image privately in external storage where gallery don’t have access. But notification manager can access?
Is there any way to create Uri form url without downloading it? I have tried this but it also not working
url = new URL(messageNotification.getAttachmentImage());
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
imageUri= Uri.parse(uri.toString());
Another workaround to show image in notification by using Messagings style like conversation as in WhatsApp
Download your image directly from url to a file in getExternalFilesDir(). Dont use an intermediate bitmap.
The MediaStore has no access to your getExternalFilesDir() so Gallery apps dont know about your files there.
The user can still use the Files app to see those images.
Then use a FileProvider to serve your files. Construct an uri with FileProvider.getUriForFile().
store your bitmap as File in some app-specific directory (not gallery) and make URI from file path. be aware of Scoped Storage and pick proper place for storing Bitmaps - check out in HERE, probably getFilesDir()/getCacheDir() method will be the best option
also worth trying may be this line:
Uri uri = Uri.parse(messageNotification.getAttachmentImage());
(encodedImageUrl = URLEncoder.encode(imageUrl, "utf-8") may be needed)

Querying mp3 cover image using glide

I've been developing an android music player and I would like to load the cover image which each mp3 tag has. I previously used the following code to extract the image but, when the list view is starts scrolling it gives a lot of errors and the app crashes at random times. The code is as following.
MediaMetadataRetriever retrieve = new MediaMetadataRetriever();
retrieve.setDataSource(songsList.get(songIndex).get("songPath"));
byte [] data = mmr.getEmbeddedPicture();
This throws an error saying the following message and at random points the application crashes.
getEmbeddedPicture: Call to getEmbeddedPicture failed
So I used the glide library to load the images using the following code.
Glide.with(parent.getContext()).load(currSong.getPath())
.placeholder(R.drawable.default_img).into(holder.albumImage);
The thing is I pass the song path to the load function but doesn't load any image to it! I logged the path and it shows the correct path to the mp3 file.
How can I load the images using the Glide library! If there is a tutorial on this, please be kind enough to let me know.
I did the following to retrieve and set the image in the list.
To retrieve album art for the song:-
This is the query
final Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.ALBUM_ID}, null, null,
"LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC");
To capture URI
long album_id=mCursor.getLong(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, album_id);
And then to set in list via Adapter
Uri uri=Uri.parse(data.get(position).getAlbum_art());
try {
bitmap = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), uri);
holder.image.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}

Android: Album Art getting replaced with some image from gallery

I built a music player app for android. In some songs when I load album art it shows some other image from gallery. It happens rarely and only in some songs even if their album art is not missing. I'm taking album art from "content://media/external/audio/albumart/" + songId. I don't understand why it is picking image from gallery from this uri. The song is showing correct image in Google play music app. It happened in a friend's phone. Instead of showing album art this URI is showing his selfie image.
I'm really exhausted trying to debug this issue. I would really appreciate any help.
There is a issue with
Images.Thumbnails.getThumbnail(contentResolver, id, Kind, options);method,
sometimes it return random image from sdcard , to workaround it use :
public Bitmap findArtworkbyAlbumId(Context activity, String albumId) {
Bitmap artwork = null;
if (albumId == null) {
return null;
}
Uri uri = Uri.parse(albumId);
Log.e("tag", uri.toString());
ContentResolver res = activity.getContentResolver();
InputStream in;
try {
in = res.openInputStream(uri);
if (in != null) {
artwork = BitmapFactory.decodeStream(in, null, null);
in.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return artwork;
}

Album art not displayed in music player in android

I'm building a music player in Android. I'm displaying the album art for currently playing song. This is my code to retrieve the embedded image:-
public Bitmap getAlbumArt(String filePath) {
Bitmap bm = null;
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(filePath);
byte [] data = mmr.getEmbeddedPicture();
// convert the byte array to a bitmap
if(data != null) {
bm = BitmapFactory.decodeByteArray(data, 0, data.length);
}
return bm;
}
This code works fine and is able to retrieve album art but only for some songs. However, I can see the album art for all the songs in thumbnail view in Windows.
Could somebody explain what might be the reason behind this? Also, if there is an alternate way to achieve the same?
Thank You!

Get cover picture by song

Is it possible to get a cover picture by song and not by album.
Because I have one self combined album with songs and they all have different cover pictures.
But when I want to query them I always get the same picture returned.
String[] ARG_STRING = {MediaStore.Audio.Media.ALBUM_ID};
...
String albumCover = _cursor.getString(_cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
...
MusicUtils.getArtwork(this, -1, Integer.parseInt(albumID));
So i would like to know how it's possible to get an cover image of an song.
I know MusicUtils supports getArtwork by SongId, but what ID should I use because MediaStore.Audio.Media._ID is not working.
I'm not familiar with MusicUtils, however, you should be able to get the cover art from the file itself by using MediaMetadataRetriever. Here is a brief code snippet showing how to use it. The uri referenced is the content uri for the file you want to retrieve the art for.
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
byte[] rawArt;
Bitmap art;
BitmapFactory.Options bfo=new BitmapFactory.Options();
mmr.setDataSource(getApplicationContext(), uri);
rawArt = mmr.getEmbeddedPicture();
// if rawArt is null then no cover art is embedded in the file or is not
// recognized as such.
if (null != rawArt)
art = BitmapFactory.decodeByteArray(rawArt, 0, rawArt.length, bfo);
// Code that uses the cover art retrieved below.

Categories

Resources