I'm brand new to Java and also android programming, so things are a little strange to me! I mainly come from a background in C++/C# so speak the tech!
Anyhow.
I'm trying to create a simple class that handles audio for a custom music player i'm designing. I've got all the keypress events handled, so now i'm working on the functionality.
I'm using the MediaPlayer
class for handling most of the hard stuff, but I'm a little confused on how to access audio that is saved on a users mobile device.
I've been doing a little research, and apparently the android device has an inbuilt database that manages the locations of all the audio, and to access this data I have to use a Uri
?
If someone could post some code samples of how to use a Uri
to access this, then i'm rather sure I will be able to build on top of that to then add the data into whatever container I desire.
Just to make clear - the music location directory isn't known by the user, and I'm not making a raw folder, I want to gain access to ALL music held on the users device where the software can then play it.
Or if that fails, a nice tutorial... I've looked at the docs gave by google, but there aren't any example codes so I don't really know where to start!
Thanks all.
Here is an example of how to use a Uri to access Audio files, this code searches for songs on the users device & stores the details in songsList.
ArrayList<HashMap<String, String>> songsList = new ArrayList<>();
String[] STAR = {"*"};
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
Cursor cursor = managedQuery(uri, STAR, selection, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String songName = cursor.getString(cursor.
getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
String path = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA));
String albumName = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM));
int albumId = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
HashMap<String, String> song = new HashMap<String, String>();
song.put("songTitle", albumName + " " + songName + "___" + albumId);
song.put("songPath", path);
songsList.add(song);
} while (cursor.moveToNext());
}
}
You're likely going to use the provided MediaStore
and query it for all found audio. It is a ContentProvider
which comes with the system and you can access it using your own ContentResolver
. Have a look at MediaStore.Audio.Media
and look at the Uri
entries there. Also see this page, the "Retrieving media from a ContentResolver" for some simple example code.
First you should think about whether or not you really want to play your audio files directly via the filesystem. The more common way to work on android is to access media files by querying the inbuilt media database instead of working directly with the file system.
If you want to work with the media database you typically do so by:
- Acquiring an instance of a content resolver (usually done by calling
getContentResolver()
in your activity)
- You can then ask the ContentResolver for the available media of a certain type. Here you come in to contact with an URI for the first time. You tell the ContentResolver which kind of media you are intersted in by specifying a specific URI for your query. Since you are interested in Music you would query android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI.
You can now query your ContentResolver like this:
Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
This is the most basic query which gives you all the registered media objects. By specifying the other (NULL) parameters you could specify filter criteria, sort criteria,etc..
Your query gives you an instance of Cursor. With your cursor instance you can basically do two things.
- You can iterate through the results of your query
- You can ask it about the column structure of your results (e.g. the index of the name column TITLE, the Artist name ARTIST and last but not least the ID column).
So lets assume you are interested only in the ID of the first song. You do this by setting your Cursor to the its beginning by calling:
cursor.moveToFirst();
You can now simply call the typed getters of cursor to access the columns you are interested in, so for example for the ID of this song you would call:
long mySongId=cursor.getLong(cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID));
If you want to know the album name you would do:
cursor.getString(android.provider.MediaStore.Audio.Media.ALBUM);
Obviously I omitted all the error handling for brevity (in a real world example you should check whether there are any songs on your device, that the query succeeded,...).
Now since you have your songs ID in mySongId you can go for the URI thing a second time. This time you can generate a fully qualified URI for your song by calling:
Uri mySongUri=ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, mySongsId);
This gives you the URI of your media file that you can then give to the mediaplayer to start playing back your file:
myMPlayer = new MediaPlayer();
myMPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
myMPlayer.setDataSource(getApplicationContext(), mySongUri);
Be sure to have a good song as the first song on your device so you get to listen to some good music after all the hard work:-)
btw.: If you want to know more about Android's ContentProvider and ContentResolver concepts you can check out this tutorial:
http://www.grokkingandroid.com/android-tutorial-content-provider-basics/