How to get songs and other media from an Album ID? - android

I want to get songs and other MEDIA details from Album Id. All I have is Album Id and I tried many solutions but none of them succeed.
My code snippet:
ContentResolver contentResolver = getContentResolver();
Uri mediaUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, albumId);
Log.wtf("SKJDBKJ", mediaUri.toString());
Cursor mediaCursor = contentResolver.query(mediaUri, null, null, null, null);
// if the cursor is null.
if(mediaCursor != null && mediaCursor.moveToFirst())
{
Log.wtf("DSJK", "entered cursor");
//get Columns
int titleColumn = mediaCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM);
int idColumn = mediaCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int artistColumn = mediaCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
// Store the title, id and artist name in Song Array list.
do
{
long thisId = mediaCursor.getLong(idColumn);
String thisTitle = mediaCursor.getString(titleColumn);
String thisArtist = mediaCursor.getString(artistColumn);
Log.wtf("Title", thisTitle);
// Add the info to our array.
songArrayList.add(new Song(thisId, thisTitle, thisArtist));
}
while (mediaCursor.moveToNext());
// For best practices, close the cursor after use.
mediaCursor.close();
}
Log for mediaUri returns path to current album, e.g. : content://media/external/audio/media/41.
Someone tell me how do I do it?

I have done it by myself.You can write simple sqlite query for 'selection' string on contentResolver.query .This example can show you how to get songs by album Id. I think this is best way.
ArrayList<Song> songs = new ArrayList<>();
String selection = "is_music != 0";
if (albumId > 0) {
selection = selection + " and album_id = " + albumId;
}
String[] projection = {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID
};
final String sortOrder = MediaStore.Audio.AudioColumns.TITLE + " COLLATE LOCALIZED ASC";
Cursor cursor = null;
try {
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
cursor = getActivity().getContentResolver().query(uri, projection, selection, null, sortOrder);
if (cursor != null) {
cursor.moveToFirst();
int position = 1;
while (!cursor.isAfterLast()) {
Song song = new Song();
song.setTitle(cursor.getString(0));
song.setDuration(cursor.getLong(4));
song.setArtist(cursor.getString(1));
song.setPath(cursor.getString(2));
song.setPosition(position);
song.setAlbumId(cursor.getLong(6));
cursor.moveToNext();
}
}
} catch (Exception e) {
Log.e("Media", e.toString());
} finally {
if (cursor != null) {
cursor.close();
}
}

I have figured it out myself after a LOT of trial and errors. I don't know if it's the best and safest way to do so, but as far as it's working I am happy.
I changed my code a bit and compared Album IDs. Here's the snippet:
ContentResolver contentResolver = getContentResolver();
Uri mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Log.wtf("SKJDBKJ", mediaUri.toString());
Cursor mediaCursor = contentResolver.query(mediaUri, null, null, null, null);
// if the cursor is null.
if(mediaCursor != null && mediaCursor.moveToFirst())
{
Log.wtf("DSJK", "entered cursor");
//get Columns
int titleColumn = mediaCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int idColumn = mediaCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int artistColumn = mediaCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int albumId = mediaCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID);
// Store the title, id and artist name in Song Array list.
do
{
long thisId = mediaCursor.getLong(idColumn);
long thisalbumId = mediaCursor.getLong(albumId);
String thisTitle = mediaCursor.getString(titleColumn);
String thisArtist = mediaCursor.getString(artistColumn);
// Add the info to our array.
if(this.albumId == thisalbumId)
{
Log.wtf("SAME2SAME", String.valueOf(thisalbumId));
Log.wtf("SAME2SAME", String.valueOf(this.albumId));
songArrayList.add(new Song(thisId, thisTitle, thisArtist));
}
}
while (mediaCursor.moveToNext());
// For best practices, close the cursor after use.
mediaCursor.close();
}
I changed:
Albums to Media in MediaStore.Audio.Audio.xxx.
Got the album Id of Media.
Compared that to album Id I receive from bundle extras.
Only add those songs in the arrayList.
I guess this'll be the way for Artists too.

when you put the cursor.movenext function in to the while loop, the first line of
MediaStore database will be passed without saving the data because the function move the cursor and then check so its better to make a value instead of putting the movenext function into the while.
try {
Projection = new String[]{
MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ALBUM
, MediaStore.Audio.Media.ARTIST,MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.SIZE};
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, Projection, null, null, null);
cursor.moveToFirst();
for (int i = 0; i < 5; i++) {
columns[i] = cursor.getColumnIndex(Projection[i]);
}
Music tempMusic = new Music();
while (next) {
tempMusic.setName(cursor.getString(columns[0]));
tempMusic.setAlbum(cursor.getString(columns[1]));
tempMusic.setArtist(cursor.getString(columns[2]));
tempMusic.setUri(cursor.getString(columns[3]));
tempMusic.setSize(cursor.getDouble(columns[4]));
if(!cursor.moveToNext())
{
next=false;
}
musicss.add(tempMusic);
tempMusic = new Music();
}

public Bitmap getAlbumArt(Long albumId) {
Bitmap albumArt = null;
try {
final Uri AlbumArtUri = Uri.parse("content://media/external/audio/albumart");
Uri uri = ContentUris.withAppendedId(AlbumArtUri, albumId);
ParcelFileDescriptor pfd = GlobalSongList.getInstance().getContentResolver().openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
albumArt = BitmapFactory.decodeFileDescriptor(fd);
}
} catch (Exception e) {
}
return albumArt;
}
ALBUM_ID is a field in the MediaStore and you can query it in the same way you query for title,artist,etc.
public Long getAlbumId(String id)
{
Cursor musicCursor;
String[] mProjection = {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ALBUM_ID};
String[] mArgs = {id};
musicCursor = musicResolver.query(musicUri, mProjection, MediaStore.Audio.Media._ID + " = ?", mArgs, null);
musicCursor.moveToFirst();
Long albumId=musicCursor.getLong(musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
return albumId;
}

This is how I did.
Works perfect.
String selection= MediaStore.Audio.Media.IS_MUSIC+"!=0";
String[] projection={
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Albums.ALBUM_ID,
MediaStore.Audio.Media.DURATION
};
Cursor cursor=getActivity().managedQuery(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,projection,selection,null,"title asc");
List<String> data=new ArrayList<>();
List<String> songs=new ArrayList<>();
List<String> artists=new ArrayList<>();
List<String> albums=new ArrayList<>();
List<String> album_id=new ArrayList<>();
List<String> durations=new ArrayList<>();
cursor.moveToFirst();
while (cursor.moveToNext()){
if(cursor.getString(5).equals(mAlbumId)) {
data.add(cursor.getString(1));
songs.add(cursor.getString(2));
artists.add(cursor.getString(3));
albums.add(cursor.getString(4));
album_id.add(mAlbumId);
durations.add(cursor.getString(6));
}
}

Related

Implementation of JOIN operation on ContentResolver?

I use #pskink solution to optimize my query code, reducing consumed time from 3000+ms to 200+ms by using ContentQueryMap.
But I still confused on how to implements JOIN operation on ContentResolver. In my limit experience, I believe consumed time will be reduced to below 100ms by using JOIN. Here is my code. How can I implements JOIN via ContentResolver?
BTW, is any optimization on my code? Thanks!
// scan Music by query table: MediaStore.Audio.AudioColumns .
private void scanMusic() {
Map<String, ContentValues> albumQueryMap = prepareAlbums();
Map<String, ContentValues> artistQueryMap = prepareArtist();
final String[] musicProjection = {
MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.SIZE,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATE_ADDED
};
final String selection = MediaStore.Audio.AudioColumns.IS_MUSIC + " != ? And "
+ MediaStore.Audio.AudioColumns.DURATION + " >= ?";
final String[] selectionArgs = new String[]{"0", "60000"};
Cursor musicCursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
musicProjection,
selection,
selectionArgs,
null
);
if (musicCursor != null) {
while (musicCursor.moveToNext()) {
// scan item music
String musicFilePath = musicCursor.getString(0);
String musicName = musicCursor.getString(1);
String musicArtist = musicCursor.getString(2);
String musicAlbumName = musicCursor.getString(3);
String albumId = musicCursor.getString(4);
String coverPath = albumQueryMap.get(albumId).getAsString(MediaStore.Audio.Albums.ALBUM_ART);
String musicFileSize = Formatter.formatFileSize(MainApplication.getBackgroundContext(), musicCursor.getLong(5));
long musicDuration = musicCursor.getLong(6);
long musicAddDate = musicCursor.getLong(7);
Music itemMusic = new Music(musicFilePath, musicName, musicArtist, musicAlbumName, coverPath, musicDuration, musicFileSize, musicAddDate);
mAllMusicList.add(itemMusic);
}
musicCursor.close();
}
}
// scan Albums by query table: MediaStore.Audio.Albums and cache it.
private Map<String, ContentValues> prepareAlbums() {
final String[] projection = {
MediaStore.Audio.Albums._ID,
MediaStore.Audio.Albums.ALBUM,
MediaStore.Audio.Albums.ALBUM_ART,
MediaStore.Audio.Albums.ARTIST,
MediaStore.Audio.Albums.FIRST_YEAR,
MediaStore.Audio.Albums.LAST_YEAR,
MediaStore.Audio.Albums.NUMBER_OF_SONGS,
};
Cursor cursor = MainApplication.getBackgroundContext().getContentResolver().query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null);
ContentQueryMap queryMap = new ContentQueryMap(
cursor,
MediaStore.Audio.Albums._ID,
false,
null
);
Map<String, ContentValues> map = queryMap.getRows();
for (String albumId : map.keySet()) {
ContentValues values = map.get(albumId);
String albumName = values.getAsString(MediaStore.Audio.Albums.ALBUM);
String albumArt = values.getAsString(MediaStore.Audio.Albums.ALBUM_ART);
String artist = values.getAsString(MediaStore.Audio.Albums.ARTIST);
String firstYear = values.getAsString(MediaStore.Audio.Albums.FIRST_YEAR);
String lastYear = values.getAsString(MediaStore.Audio.Albums.LAST_YEAR);
int numberOfSongs = values.getAsInteger(MediaStore.Audio.Artists.Albums.NUMBER_OF_SONGS);
Album item = new Album(albumName, albumArt, artist, firstYear, lastYear, numberOfSongs);
mAlbumList.add(item);
}
try {
return map;
} finally {
cursor.close();
queryMap.close();
}
}
// scan Artist by query table:MediaStore.Audio.Artists and cache it.
private Map<String, ContentValues> prepareArtist() {
final String[] projection = {
MediaStore.Audio.Artists._ID,
MediaStore.Audio.Artists.ARTIST,
MediaStore.Audio.Artists.NUMBER_OF_ALBUMS,
MediaStore.Audio.Artists.NUMBER_OF_TRACKS,
};
Cursor cursor = MainApplication.getBackgroundContext().getContentResolver().query(
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null);
ContentQueryMap queryMap = new ContentQueryMap(
cursor,
MediaStore.Audio.Artists._ID,
false,
null
);
Map<String, ContentValues> map = queryMap.getRows();
for (String artistId : map.keySet()) {
ContentValues values = map.get(artistId);
String artist = values.getAsString(MediaStore.Audio.Artists.ARTIST);
int numberOfAlbums = values.getAsInteger(MediaStore.Audio.Artists.NUMBER_OF_ALBUMS);
int numberOfTracks = values.getAsInteger(MediaStore.Audio.Artists.NUMBER_OF_TRACKS);
Artist item = new Artist(artist, numberOfAlbums, numberOfTracks);
mArtistList.add(item);
}
try {
return map;
} finally {
cursor.close();
queryMap.close();
}
}
As #pskink say, just use ContentQueryMap to optimize the query. Why
can ContentQueryMap improve my query code efficiency?
I Wrote Code Like This Before:
private void scanMusic() {
final String[] musicProjection = {
MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.SIZE,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATE_ADDED
};
final String selection = MediaStore.Audio.AudioColumns.IS_MUSIC + " != ? And "
+ MediaStore.Audio.AudioColumns.DURATION + " >= ?";
final String[] selectionArgs = new String[]{"0", "60000"};
Cursor musicCursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
musicProjection,
selection,
selectionArgs,
null
);
if (musicCursor != null) {
while (musicCursor.moveToNext()) {
// scan item music
String musicFilePath = musicCursor.getString(0);
String musicName = musicCursor.getString(1);
String musicArtist = musicCursor.getString(2);
String musicAlbumName = musicCursor.getString(3);
String albumId = musicCursor.getString(4);
// Scan the album form once for each row of the music form
String coverPath = getThumbAlbum(albumId);
String musicFileSize = Formatter.formatFileSize(context, musicCursor.getLong(5));
long musicDuration = musicCursor.getLong(6);
long musicAddDate = musicCursor.getLong(7);
Music itemMusic = new Music(musicFilePath, musicName, musicArtist, musicAlbumName, coverPath, musicDuration, musicFileSize, musicAddDate);
mAllMusicList.add(itemMusic);
}
musicCursor.close();
}
}
private String getThumbAlbum(String albumId) {
ContentResolver resolver = context.getContentResolver();
Uri albumUri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
String id = MediaStore.Audio.Albums._ID;
String[] selection = new String[]{MediaStore.Audio.Albums.ALBUM_ART};
String[] selectionArgs = new String[]{albumId};
Cursor cursor = resolver.query(albumUri, selection, id + "=?", selectionArgs, null);
if (cursor != null && cursor.moveToNext()) {
try {
return cursor.getString(0);
} finally {
cursor.close();
}
}
return null;
}
How to optimize my code? The answer is obvious. By caching Albums form query result, we can reduce the query time of Albums form.
By using ContentQueryMap, we can reach the result that we expect。
I Wrote Code Like This After:
private void scanMusic() {
Map<String, ContentValues> albumQueryMap = prepareAlbums();
final String[] musicProjection = {
MediaStore.Audio.AudioColumns.DATA,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID,
MediaStore.Audio.Media.SIZE,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.DATE_ADDED
};
final String selection = MediaStore.Audio.AudioColumns.IS_MUSIC + " != ? And "
+ MediaStore.Audio.AudioColumns.DURATION + " >= ?";
final String[] selectionArgs = new String[]{"0", "60000"};
Cursor musicCursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
musicProjection,
selection,
selectionArgs,
null
);
if (musicCursor != null) {
while (musicCursor.moveToNext()) {
// scan item music
String musicFilePath = musicCursor.getString(0);
String musicName = musicCursor.getString(1);
String musicArtist = musicCursor.getString(2);
String musicAlbumName = musicCursor.getString(3);
String albumId = musicCursor.getString(4);
String coverPath = albumQueryMap.get(albumId).getAsString(MediaStore.Audio.Albums.ALBUM_ART);
String musicFileSize = Formatter.formatFileSize(context, musicCursor.getLong(5));
long musicDuration = musicCursor.getLong(6);
long musicAddDate = musicCursor.getLong(7);
Music itemMusic = new Music(musicFilePath, musicName, musicArtist, musicAlbumName, coverPath, musicDuration, musicFileSize, musicAddDate);
mAllMusicList.add(itemMusic);
}
musicCursor.close();
}
}
// Caching the query result of Albums form into a Map, with Which we can get coverPath easily by given key.
private Map<String, ContentValues> prepareAlbums() {
final String[] projection = {
MediaStore.Audio.Albums._ID,
MediaStore.Audio.Albums.ALBUM,
MediaStore.Audio.Albums.ALBUM_ART,
MediaStore.Audio.Albums.ARTIST,
MediaStore.Audio.Albums.FIRST_YEAR,
MediaStore.Audio.Albums.LAST_YEAR,
MediaStore.Audio.Albums.NUMBER_OF_SONGS,
};
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null
);
ContentQueryMap queryMap = new ContentQueryMap(
cursor,
MediaStore.Audio.Albums._ID,
false,
null
);
try {
return queryMap.getRows();
} finally {
cursor.close();
queryMap.close();
}
}
Before I use ContentQueryMap, the program use 3000+ms on querying with result size == 273. After using ContentQueryMap, the program use just 200+ms, 15x faster, awesome.

IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it

I am new to android. I am implementing music player using service. Here is the code in which error is focused. Can anyone help me out to solve this error?
public void getSong() {
ContentResolver contentResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(musicUri, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
long thisId = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media._ID));
String thisTitle = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String thisArtist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
int albumId = cursor.getColumnIndex(android.provider.MediaStore.Audio.Albums.ALBUM_ART);
String thisArt = cursor.getString(albumId);
musicArrayList.add(new Music(thisId, thisTitle, thisArtist, thisArt));
} while (cursor.moveToNext());
}
}
Make sure table in which you are fetching the data having same column name
Check out this http://www.rjkfw.com/android/s3035.html
Check null before extracting data.
ListView audioListView = (ListView) findViewById(R.id.songView);
ArrayList<string> audioList = new ArrayList<>();
String[] proj = { MediaStore.Audio.Media._ID,MediaStore.Audio.Media.DISPLAY_NAME };// Can include more data for more details and check it.
Cursor audioCursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
if(audioCursor != null){
if(audioCursor.moveToFirst()){
do{
int audioIndex = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);
audioList.add(audioCursor.getString(audioIndex));
}while(audioCursor.moveToNext());
}
}
audioCursor.close();
ArrayAdapter<string> adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,android.R.id.text1, audioList);
audioListView.setAdapter(adapter);
Error Solved, Since I was looking for album of particular song, null value is passed in cursor. so I changed my code of cursor as below:
public void getSong() {
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM},
MediaStore.Audio.Media.IS_MUSIC + "=1",
null,
null);
if (cursor != null && cursor.moveToFirst()) {
do {
long thisId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
String thisTitle = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String thisArtist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
String thisImage = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
songList.add(new Music(thisId, thisTitle, thisArtist, thisImage));
}while (cursor.moveToNext());
}
And I have tried by calling getsongImage(URI) method in playSong() in service class for getting Album as below:
public void getSongImage(Uri uri) {
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(this,uri);
byte [] data = mmr.getEmbeddedPicture();
if(data==null){
activitySongDetailBinding.imgMusic.setImageResource(R.drawable.img);
}else {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
activitySongDetailBinding.imgMusic.setImageBitmap(bitmap);
}
}
where uri=ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songsArrayList.get(songPosn).getId())

How to get audio path to play audio file?

This is my code that gets list of songs:
List<String> getsonglist() {
List<String> songlist = new ArrayList<>();
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
// query failed, handle error.
} else if (!cursor.moveToFirst()) {
// no media on the device
} else {
int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
do {
long thisId = cursor.getLong(idColumn);
String thisTitle = cursor.getString(titleColumn);
// ...process entry...
songlist.add(thisTitle);
} while (cursor.moveToNext());
}
return songlist;
}
I want to play that song by giving its path to music player() method.
You can get full path like this:
String fullPath = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
So, Your function would be:
List<String> getsonglist() {
List<String> songlist = new ArrayList<>();
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
// query failed, handle error.
} else if (!cursor.moveToFirst()) {
// no media on the device
} else {
do {
String fullPath = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
// ...process entry...
Log.e("Full Path : ", fullPath);
songlist.add(fullPath);
} while (cursor.moveToNext());
}
return songlist;
}
Try this one
String fullPath = cursor.getString(cursor.getColumnIndex("_data"));

How to display music name by playlist name Android programming

There are some similar questions have been posted here, I have used those suggestions and tried it in different ways, but still no results for getting out, my codes is like this:
private Cursor getPlaylists(String playlistName) {
Cursor cursor = null;
String[] projection1 = { MediaStore.Audio.Playlists._ID,
MediaStore.Audio.Playlists.NAME };
cursor = this.managedQuery(
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, projection1,
MediaStore.Audio.Playlists.NAME + "=\"" + playlistName + "\"", null,
null); // I need to put "" for the string, otherwise sqlite errors for no such table
startManagingCursor(cursor);
cursor.moveToFirst();
String playlist_id = cursor.getString(0);
Long playlist_id2 = cursor.getLong(0);
if (playlist_id2 > 0) {
String[] projection = {
MediaStore.Audio.Playlists.Members.AUDIO_ID,
MediaStore.Audio.Playlists.Members.ARTIST,
MediaStore.Audio.Playlists.Members.TITLE,
MediaStore.Audio.Playlists.Members._ID
};
cursor = getContentResolver().query(MediaStore.Audio.Playlists.Members.getContentUri("external",playlist_id2),
projection,
null,
null,
null);
}
return cursor;
But after these codes, how can I exactly get music list names? does then store in projection, but my projection variable are always no music list information inside. If I need to iterate this cursor again to get music list names, how can I do it, I have tried this way.. but it won't work.
// startManagingCursor(cursor);
for (boolean hasItem = cursor.moveToFirst(); hasItem; hasItem = cursor
.moveToNext()) {
String musicName = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Playlists.Members.TITLE));
Log.i(LOGGING_TAG, musicName);
}
it looks like hasItem is null as always. I am stuck on this for couple of hours, maybe that is a stupid question but any suggestions would be graceful.
If I understand you correctly, you want to list the tracks on a given playlist.
This is how I do it. Once you have your cursor, you just loop around it by getting the values you need.
see examples below :
public Cursor getPlaylistTracks(Context context, Long playlist_id) {
Uri newuri = MediaStore.Audio.Playlists.Members.getContentUri("external",playlist_id);
ContentResolver resolver = context.getContentResolver();
String _id = MediaStore.Audio.Playlists.Members._ID;
String audio_id = MediaStore.Audio.Playlists.Members.AUDIO_ID;
String artist = MediaStore.Audio.Playlists.Members.ARTIST;
String album = MediaStore.Audio.Playlists.Members.ALBUM;
String title = MediaStore.Audio.Playlists.Members.TITLE;
String duration = MediaStore.Audio.Playlists.Members.DURATION;
String location = MediaStore.Audio.Playlists.Members.DATA;
String composer = MediaStore.Audio.Playlists.Members.COMPOSER;
String playorder = MediaStore.Audio.Playlists.Members.PLAY_ORDER;
String date_modified = MediaStore.Audio.Playlists.Members.DATE_MODIFIED;
String[] columns = { _id, audio_id, artist, album, title, duration,
location, date_modified, playorder, composer };
Cursor cursor = resolver.query(newuri, columns, null, null, null);
return cursor;
}
if (cursor!= null){
cursor.moveToFirst();
int artistColumn = cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.ARTIST);
int durationColumn = cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.DURATION);
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
{
artist = cursor.getString(artistColumn);
duration = duration + cursor.getLong(durationColumn);
// do something else
}
cursor.close();
}

Given an Android music playlist name, how can one find the songs in the playlist?

The playlist names can be found by a query on MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI
and then look at the MediaStore.Audio.PlaylistsColumns.NAME column.
There is a data column too, MediaStore.Audio.PlaylistsColumns._DATA, but it is returning null.
The list of songs (MediaStore.Audio.Media.EXTERNAL_CONTENT_URI/id) do not seem to show any playlist affiliation.
Here is a bit from my program:
The gist is that you need the id for the playlist to grab the songs.
Basically you can take my code and change the where statement to .NAME +" = '"+name+"'",
private Cursor getPlaylists(String playlistId){
Cursor cursor = null;
String[] projection1 = {
MediaStore.Audio.Playlists._ID,
MediaStore.Audio.Playlists.NAME
};
cursor = this.managedQuery(
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
projection1,
MediaStore.Audio.Playlists._ID+ " = "+playlistId+"",
null,
null);
startManagingCursor(cursor);
cursor.moveToFirst();
playlist_id = cursor.getString(0);
playlist_id2 = cursor.getLong(0);
if(playlist_id2 > 0){
String[] projection = {
MediaStore.Audio.Playlists.Members.AUDIO_ID,
MediaStore.Audio.Playlists.Members.ARTIST,
MediaStore.Audio.Playlists.Members.TITLE,
MediaStore.Audio.Playlists.Members._ID
};
cursor = null;
cursor = this.managedQuery(
MediaStore.Audio.Playlists.Members.getContentUri("external",playlist_id2 ),
projection,
MediaStore.Audio.Media.IS_MUSIC +" != 0 ",
null,
null);
}
cManager(cursor,2,1);
return cursor;
}
Here is a working way to get tracks from a play list. Basically it loops the cursor through all the of the playlist query, and each time it gets the id of a member (track) and using that id of the track we can get other data such as path, artist, duration, album etc.
ContentResolver contentResolver = getContentResolver();
Uri playListUri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistID); //playlistID is the _ID of the given playlist
MediaMetadataRetriever mr = new MediaMetadataRetriever();
Cursor cursor = contentResolver.query(playListUri, null, null, null, null);
if(cursor != null)
{
if(cursor.moveToNext()) {
do {
String track_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.AUDIO_ID));
Uri mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] trackProjection = new String[]{MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.DATA};
String selection = MediaStore.Audio.Media._ID + "=?";
String[] selectionArgs = new String[]{"" + track_id};
Cursor mediaCursor = contentResolver.query(mediaContentUri, trackProjection, selection, selectionArgs, null);
if (mediaCursor != null) {
if (mediaCursor.getCount() >= 0) {
mediaCursor.moveToPosition(0);
String song_title = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String song_artist = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String song_album = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
String song_path = mediaCursor.getString(mediaCursor.getColumnIndex(MediaStore.Audio.Media.DATA));
}
}
} while (cursor.moveToNext());
}
}
this is the way to get all playlist from the device
public ArrayList<String> getPlayList() {
ArrayList<String> arrayList=new ArrayList<String>();
String[] proj = {"*"};
Uri tempPlaylistURI = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
// In the next line 'this' points to current Activity.
// If you want to use the same code in other java file then activity,
// then use an instance of any activity in place of 'this'.
Cursor playListCursor= activity.managedQuery(tempPlaylistURI, proj, null,null,null);
if(playListCursor == null){
System.out.println("Not having any Playlist on phone --------------");
return arrayList;//don't have list on phone
}
System.gc();
String playListName = null;
System.out.println(">>>>>>> CREATING AND DISPLAYING LIST OF ALL CREATED PLAYLIST <<<<<<");
for(int i = 0; i <playListCursor.getCount() ; i++)
{
playListCursor.moveToPosition(i);
playListName = playListCursor.getString(playListCursor.getColumnIndex("name"));
System.out.println("> " + i + " : " + playListName );
arrayList.add(playListName);
}
if(playListCursor != null)
playListCursor.close();
return arrayList;
}

Categories

Resources