I'm writing an app that can play all audio files present in MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.
Here's a bit of what I have so far:
String[] projection = {MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.DATA};
Cursor cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null);
while (cursor.moveToNext()) {
String uri = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
// Use uri to play music...
}
And this works fine. I'm able to play the audio by passing the uri to a MediaPlayer.
However...
MediaStore.Audio.Media.DATA has no guarantees of holding a uri. To my understanding, it can hold absolutely anything.
MediaStore.Audio.Media.DATA is deprecated.
Is there any way to play the audio items in external storage, without relying on MediaStore.Audio.Media.DATA?
Yes, it is.
You can simply play it with the ContentUris.withAppendedId, as MediaPlayer has a method for playing content by Uri.
Here, for example, i'm setting the song Uri.
/// Helper function
public static Uri getSongUri(int songId) {
return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
}
/// And then...
public void setUri(Context appContext, int songId) {
// ....
player.setDataSource(appContext, getSongUri(songId));
// ....
}
Related
Using this method of audio file retrieval from Android's external storage
Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
can I actually find a resonable way to fetch a genre of the given song? MediaStore class seems to provide everything else - from song's title to its composer info - except for the genre field. Should I use MediaMetadataRetriever then? If so, how drastically can creating a MediaMetadataRetriever instance for every song on a device reduce app's performance?
Maybe there are some better ways to retrieve all audio files from both external and internal storages in android?
As mentioned at Developer's Site,
You can fetch the Genres of the Audio file using MediaStore.Audio.Genres
Sample Code :
private static String[] genresProj = {
MediaStore.Audio.Genres.NAME,
MediaStore.Audio.Genres._ID
};
int idIndex = cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
while (cursor.moveToNext()){
int id = Integer.parseInt(mediaCursor.getString(idIndex));
Uri uri = MediaStore.Audio.Genres.getContentUriForAudioId("external", id );
genresCursor = context.getContentResolver().query(uri,
genresProj , null, null, null);
int genreIndex = genresCursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME);
while (genresCursor.moveToNext()) {
Log.d(TAG, "Genre = " +genresCursor.getString(genreIndex));
}
}
}
To fetch other details of the Audio file, please check here .
I want to make an mp3 app in which the user gives a text and then it plays that song. So far, I have this function in mind:
public void searchSong(String x) {
mp = MediaPlayer.create(MainActivity.this, R.raw.x);
mp.start();
}
where x is the name stored, But ofcourse this gives an error saying "x cannot be resolved or is not a field". How can I fix that? Thanks a lot
If your songs have already stored in a specific location of sdcard,you can get the uri of song file ,then use mp.setDataSource() to bind what will be played.
If you want to search songs by specific song name, you can use android.provider.MediaStore.The Media provider contains meta data for all available media on both internal and external storage devices include song name.
A simple query code snippet is like this:
public void searchSong(String songName) {
final String[] projections = new String[] {
android.provider.MediaStore.Audio.Media.ARTIST,
android.provider.MediaStore.Audio.Media.DATA };
final String selection = Media.TITLE + " = ?";
final String[] selectionArgs = new String[] { songName };
Cursor cursor = mContentResolver
.query(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projections, selection, selectionArgs,
Media.DEFAULT_SORT_ORDER);
if (cursor != null) {
int indexFilePath = cursor.getColumnIndex(Media.DATA);
int indexArtist = cursor.getColumnIndex(Media.ARTIST);
while (cursor.moveToNext()) {
// Get the informations of the song
cursor.getString(indexArtist);
cursor.getString(indexFilePath);
// Then do what you want
}
cursor.close();
}
}
I am trying to get a song from a playlist then play it in android.
All answers i can find relies on
MediaStore.MediaColumn.DATA
to find the file path and then feed it to the MediaPlayer.
But when i tried to do it, i kept getting "invalid column _data" exception.I can still query for other stuff about the song, like the "AUDIO_ID". So my question is, is it possible to play the song with only the "AUDIO_ID" known? How? Or is there something that i am missing for the "data", since every other people are able to use it.
This is my code for getting playlist.
private Cursor getPlaylistCursor() {
String[] proj = { MediaStore.Audio.Playlists._ID,MediaStore.Audio.Playlists.NAME };
Uri playlistUri = Uri.parse("content://com.google.android.music.MusicConten/playlists");
Cursor playlistCursor = getContentResolver().query(playlistUri, proj,null, null, null);
playlistCursor.moveToFirst();
return playlistCursor;
}
This is what i am working on for getting song, as i said, i cannot query the "data", if the "data" argument is added to the projection, i get an exception.
private void getSongListCursor(Long playlistID) {
String[] proj2 = { MediaStore.Audio.Playlists.Members.TITLE,
MediaStore.Audio.Playlists.Members.AUDIO_ID };
String playListRef = "content://com.google.android.music.MusicContent/playlists/"
+ playlistID + "/members";
Uri songUri = Uri.parse(playListRef);
Cursor songCursor = getContentResolver().query(songUri, proj2, null,
null, null);
}
SO now, i have the audio ID of a song, how do i play it?
Everything is possible ;-)
My approach is to use the Google Play Music server to obtain the streaming URL corresponding to the selected song ID. Just let me know if you need help with authentication and jump-start with the unofficial API for Google Play Music.
In the class MediaStore.Files class, its mentioned that,
Media provider table containing an index of all files in the media storage, including non-media files.
I'm interested in querying for non-media files like PDF.
I'm using CursorLoader to query the database. The second parameter for the constructor requires an Uri argument which is easy to get for the media types Audio, Images and Video as each of them have a EXTERNAL_CONTENT_URI and INTERNAL_CONTENT_URI constant defined for them.
For MediaStore.Files there is no such defined constant. I tried using the getContentUri() method but couldn't figure out the argument value for volumeName. I tried giving "/mnt/sdcard" and also the volume name that appears when I connect the device to my system but in vain.
I saw a similar question on Google Groups but that is not resolved.
EDIT: I also tried using Uri.fromFile(new File("/mnt/sdcard/")) and Uri.parse(new File("/mnt/sdcard").toString()) but that didn't work out either.
It is "external" or "internal" although internal (system files) is probably not useful here.
ContentResolver cr = context.getContentResolver();
Uri uri = MediaStore.Files.getContentUri("external");
// every column, although that is huge waste, you probably need
// BaseColumns.DATA (the path) only.
String[] projection = null;
// exclude media files, they would be here also.
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_NONE;
String[] selectionArgs = null; // there is no ? in selection so null here
String sortOrder = null; // unordered
Cursor allNonMediaFiles = cr.query(uri, projection, selection, selectionArgs, sortOrder);
If you want .pdf only you could check the mimetype
// only pdf
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + "=?";
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
String[] selectionArgsPdf = new String[]{ mimeType };
Cursor allPdfFiles = cr.query(uri, projection, selectionMimeType, selectionArgsPdf, sortOrder);
In my app I want to set the ringtone when I get an incoming call... How to open the SDCARD and get audio files and list it.. How to get the URI for the selected audio file..
MediaScanner finds music for you, populating the MediaStore database. Here's some code to look up a music entry:
final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
final String[] cursor_cols = {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.TITLE,
};
final String where = MediaStore.Audio.Media.IS_MUSIC + "=1";
final Cursor cursor = getContentResolver().query(uri, cursor_cols, where, null, null);
cursor.moveToNext();
final String artist = cursor.getString(_cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
final String album = cursor.getString(_cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
final String track = cursor.getString(_cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
doSomethingHere(artist, album, track);
The "data" field contains a handle you can use with MediaPlayer. while doing this media files scanning and indexing for the first time, scan it using a AsyncTask, but later when a intent is received do it using a service.