2009-12-22

[Android] The PLAYER_SET_DATA_SOURCE error when using MediaPlayer.setDataSource()

When an MediaPlayer object is used like this,
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.in_call_ringtone);
mMediaPlayer.setDataSource(afd.getFileDescriptor());
afd.close();                                                                                      mMediaPlayer.setVolume(IN_CALL_VOLUME, IN_CALL_VOLUME);
mMediaPlayer.prepare();
You will see error messages in logcat,
E/PlayerDriver(  556): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
E/MediaPlayer(  879): error (1, -4)

It is because the FileDescriptor returns from afd.getFileDescriptor() represents the whole apk file. The MediaPlayer has no idea about how to play it. And you have evidence from documentation of AssetFileDescriptor to prove this point. It says,
AssetFileDescriptor A new file descriptor you can use to read
the resource. This includes the file descriptor itself, as well
as the offset and length of data where the resource appears in
the file. A null is returned if the file exists but is compressed.

Hence, the setDataSource() should be used as,
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.in_call_ringtone);                 mMediaPlayer.setDataSource(afd.getFileDescriptor(),
                           afd.getStartOffset(),
                           afd.getLength());
afd.close();
mMediaPlayer.setVolume(IN_CALL_VOLUME, IN_CALL_VOLUME);
mMediaPlayer.prepare();