Understanding the setData Source Method

In Listing 9-2, we called the create() method to load the audio file from a raw resource. With this approach, you don't need to call setDataSource(). Alternatively, if you instantiate the MediaPlayer yourself using the default constructor, or if your media content is not accessible through a resource ID or a URL, you'll need to call setDataSource().

The setDataSource() method has overloaded versions that you can use to customize the data source for your specific needs. For example, Listing 9-3 shows how you can load an audio file from a raw resource using a FileDescriptor.

Listing 9-3. Setting the MediaPlayer's Data Source Using a FileDescriptor private void playLocalAudio_UsingDescriptor() throws Exception {

AssetFileDescriptor fileDesc = getResources().openRawResourceFd( R.raw.music_file);

mediaPlayer = new MediaPlayer();

mediaPlayer.setDataSource(fileDesc.getFileDescriptor(), fileDesc .getStartOffset(), fileDesc.getLength());

fileDesc.close();

mediaPlayer.prepare();

mediaPlayer.start();

The code in Listing 9-3 assumes that it's within the context of an activity. As shown, you call the getResources() method to get the application's resources and then use the openRawResourceFd() method to get a file descriptor for an audio file within the /res/raw folder. You then call the setDataSource() method using the AssetFileDescriptor, the starting position to begin playback, and the ending position. You can also use this version of setDataSource() if you want to play back a specific portion of an audio file. If you always want to play the entire file, you can call the simpler version of setDataSource(FileDescriptor desc), which does not require the initial offset and length.

Using one of the setDataSource() methods with the FileDescriptor can also be handy if you want to feed a media file located within your application's /data directory. For security reasons, the media player does not have access to an application's /data directory, but your application can open the file and then feed the (opened) FileDescriptor to setDataSource(). Realize that the application's /data directory resides in the set of files and folders under /data/data/APP_PACKAGE_NAME/. You can get access to this directory by calling the appropriate method from the Context class, rather than hard-coding the path. For example, you can call getFilesDir() on Context to get the current application's files directory. Currently, this path looks like the following: /data/data/APP_PACKAGE_NAME/files. Similarly, you can call getCacheDir() to get the application's cache directory. Your application will have read and write permission on the contents of these folders, so you can create files dynamically and feed them to the player.

Observe that an application's /data directory differs greatly from its /res/raw folder. The /raw folder is physically part of the .apk file, and it's static—that is, you cannot modify the .apk file dynamically. The contents of the /data directory, on the other hand, are dynamic.

Finally, if you use FileDescriptor, as shown in Listing 9-3, be sure to close the handle after calling setDataSource().

This concludes our discussion about playing audio content, so we'll now turn our attention to playing video. As you'll see, referencing video content is similar to referencing audio content. But we have not yet talked about playing content from the device's SD card, so we'll delve into that along the way.

0 0

Post a comment