Mediastore.Audio.Media.DATA return nothing - android

I tried to list all audio file with a Cursor and Content resolver, I get song title, artist of songs and Id but the problem is that I can't get the path it return nothing when I try to display it in Toast.
Thanks for your help.
Here is the code and how I get songs:
ContentResolver musicResolver = this.getContentResolver();
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri,
null,
null,
null,
MediaStore.Audio.Media.TITLE + " ASC");
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int idColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int titleColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int pathColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
//add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
String thisPath = musicCursor.getString(pathColumn);
arrayChansons.add(new Chanson(thisId, thisTitle, thisArtist, thisPath));
}
while (musicCursor.moveToNext());
musicCursor.close();

Related

Android 8.1 lost responsiveness

When I launch my application after upgrading from android 7 to 8.1 I noticed that it lost a lot of responsiveness.
When I'm trying to get songs from device memory I get a lot of errors like:
E/SEC_DRM_PLUGIN_Omafl: OmaPlugin::onOpenDecryptSession(fd)::Drm2IsDrmFileByExtFd::file is NOT DRM by extension
That works much slower than on the Android 7.
Code:
public ArrayList<Song> getSongList() {
MediaMetadataRetriever metaRetriver = new MediaMetadataRetriever();
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
ArrayList<Song> songList = new ArrayList<>();
ContentResolver musicResolver = context.getContentResolver();
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, selection, null, null);
if (musicCursor != null && musicCursor.moveToFirst()) {
int titleColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int durationColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.DURATION);
int column_index = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
do {
long id = musicCursor.getLong(idColumn);
String path = musicCursor.getString(column_index);
String title = musicCursor.getString(titleColumn);
String artist = musicCursor.getString(artistColumn);
String duration = musicCursor.getString(durationColumn);
try {
metaRetriver.setDataSource(path);
songList.add(new Song(id, title, artist, path, duration));
}catch (Exception exc){}
} while (musicCursor.moveToNext());
}
return songList;
}
I had to delete the one line of code that was causing the error when trying to get every single song from memory:
mediaMetadataRetriver.setDataSource(pathOfSong);
Hope it will help you.

How to list all music in MediaStore without app songs

I used this code to get all music in MediaStore but not only music, my list has all music in my device and application's sound like "facebook" or "skype". How to avoid that?
public void getSongList(){
//query external audio
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Toast.makeText(PlayListActivity.this, musicUri.getPath(), Toast.LENGTH_LONG).show();
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
//iterate over results if valid
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
int albumColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ALBUM_ID);
//add songs to list
Bitmap bmThumbnail;
do {
String path = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA));
long thisId = musicCursor.getLong(idColumn);
long thisAlbumId = musicCursor.getLong(albumColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
songList.add(new Song(thisId, thisAlbumId, thisTitle, thisArtist, path));
}
while (musicCursor.moveToNext());
}
}
I am not certain about this but I did it in the following way.
public void getSongList(){
//query external audio
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Toast.makeText(PlayListActivity.this, musicUri.getPath(), Toast.LENGTH_LONG).show();
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
//iterate over results if valid
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
int albumColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ALBUM_ID);
int songDuration = musicCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.DUration);
//add songs to list
Bitmap bmThumbnail;
do {
String path = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA));
long thisId = musicCursor.getLong(idColumn);
long thisAlbumId = musicCursor.getLong(albumColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
int dur = Integer.parseInt(musicCursor.getString(songDuration));
if(dur>5000){
songList.add(new Song(thisId, thisAlbumId, thisTitle, thisArtist, path));}
}
while (musicCursor.moveToNext());
}
}
Another way might be to do it with directory maybe?

How to get album cover querying songs

how can I get "cover songs" (so songs in the same album have the same cover)?
// Retrieve song info from device
public void getSongList() {
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
// Query external audio
ContentResolver musicResolver = getActivity().getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, selection, null, null);
// Iterate over results if valid
if (musicCursor != null && musicCursor.moveToFirst()) {
// Get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
int durationColumn = musicCursor.getColumnIndex
(MediaStore.Audio.Media.DURATION);
// Add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
long thisDuration = musicCursor.getLong(durationColumn);
String thisPathAlbumImage = ????
//**** HERE I WANT A PATH/URI WITH ALBUM SONG ****
arrayOfSongs.add(new Song(thisId, thisTitle, thisArtist, thisDuration, thisPathAlbumImage));
Log.d(LOG_TAG, "New song added: " + thisTitle);
}
while (musicCursor.moveToNext());
}
}
I need another query? I don't want a query about all albums, I don't know how connect songs to albums...
You need to include the album id in your query above.
int albumIdColumn = musicCursor.getColumnIndex
(MediaStore.Audio.Media.ALBUM_ID);
long albumId = musicCursor.getLong(albumIdColumn);
With the album id you can query for the path of the cover like this:
private static String getCoverArtPath(long albumId, Context context) {
Cursor albumCursor = context.getContentResolver().query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Albums.ALBUM_ART},
MediaStore.Audio.Albums._ID + " = ?",
new String[]{Long.toString(albumId)},
null
);
boolean queryResult = albumCursor.moveToFirst();
String result = null;
if (queryResult) {
result = albumCursor.getString(0);
}
albumCursor.close();
return result;
}

Android <unknown> Genre in MediaStore

Is there a way to query for genres in MediaStore and also find songs that don't have a genre set?
This code returns all songs that have a genre set but skips those that don't have a genre.
String[] proj1 = new String[]{
MediaStore.Audio.Genres.NAME,
MediaStore.Audio.Genres._ID
};
ContentResolver cr = activity.getContentResolver();
genreCursor = cr.query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI, proj1, null, null, null);
if (genreCursor.moveToFirst()) {
while (genreCursor.moveToNext()) {
int index = genreCursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME);
String genre = genreCursor.getString(index);
index = genreCursor.getColumnIndexOrThrow(MediaStore.Audio.Genres._ID);
long genreId = Long.parseLong(genreCursor.getString(index));
Uri uri = MediaStore.Audio.Genres.Members.getContentUri("external", genreId);
Cursor tempCursor = cr.query(uri, projection, null, null, null);
if (tempCursor.moveToFirst()) {
while (tempCursor.moveToNext()) {
index = tempCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE);
String title = tempCursor.getString(index);
index = tempCursor.getColumnIndexOrThrow(MediaStore.Audio.Artists.ARTIST);
String artist = tempCursor.getString(index);
index = tempCursor.getColumnIndexOrThrow(MediaStore.Audio.Albums.ALBUM);
String album = tempCursor.getString(index);
songs.add(new Song(artist, title, album, genre));
}
tempCursor.close();
}
}
I am looking for a way to find those songs that have an unknown genre set. Is the only possibility to query all songs and then cross-check them with those that have a genre set to have a list of all songs with the genre for those that have it set?
Songs with unknown genre will have genre as "unknown". So, you'll be getting the the list of all the songs on the device.
I am using this code to scan all the songs with genres and store it in SQLitedatabase. Hope this will help you and this code also return genres.
int index;
int genres;
long genreId;
int count;
Uri uri;
Cursor genrecursor;
Cursor musicCursor;
db = new DBhelper(getApplicationContext()).getReadableDatabase();
String[] proj1 = {MediaStore.Audio.Genres.NAME, MediaStore.Audio.Genres._ID};
genrecursor=getApplicationContext().getContentResolver().query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI,proj1,null, null, null);
if(genrecursor.moveToFirst())
{
do{
genres = genrecursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME);
System.out.println("GENRE NAME: "+genrecursor.getString(genres));
System.out.println("======================================");
index = genrecursor.getColumnIndexOrThrow(MediaStore.Audio.Genres._ID);
genreId=Long.parseLong(genrecursor.getString(index));
uri = MediaStore.Audio.Genres.Members.getContentUri("external", genreId);
musicCursor = getApplicationContext().getContentResolver().query(uri, null, null,null,null);
System.out.println("Total Songs: "+musicCursor.getCount());
if(musicCursor.moveToFirst())
{
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
int albumId = musicCursor.getColumnIndex
(MediaStore.Audio.Media.ALBUM_ID);
int data = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
int albumkey = musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_KEY);
int albumName = musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM);
int artwork = musicCursor.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
do{
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
long thisalbumId = musicCursor.getLong(albumId);
String thisdata = musicCursor.getString(data);
String AlbumKey = musicCursor.getString(albumkey);
String thisAlbum = musicCursor.getString(albumName);
String thisGenres = genrecursor.getString(genres);
ContentValues value = new ContentValues();
value.put("songtitle", thisTitle);
value.put("songartist", thisArtist);
value.put("songpath", thisdata);
value.put("songalbum", thisAlbum);
value.put("songgenres", thisGenres);
try {
db.insertOrThrow("songListRecord", null, value);
}
catch (SQLiteConstraintException e)
{
}
}while(musicCursor.moveToNext());
}
System.out.println("======================================");
}while(genrecursor.moveToNext());
}

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

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));
}
}

Categories

Resources