finiteloop finiteloop - 6 months ago 58
Android Question

(Android MediaPlayer) How am I supposed to call setAudioStreamType() if MediaPlayer.create() implicitly calls prepare()?

I am writing an Android alarm application that uses a Service in order to play the alarm tone. Currently, I am able to get the audio to play, but it plays in a form that can be muted by turning down the device's volume. Thus, I am trying to add a call to

setAudioStreamType(AudioManager.STREAM_ALARM);
to prevent this.

I have the following for my
onStartCommand()
function for the service:

MediaPlayer mMP;
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
try
{
mMP = MediaPlayer.create(this, R.raw.alarm);
mMP.setAudioStreamType(AudioManager.STREAM_ALARM);
mMP.setLooping(true);
//mMP.prepare(); commented out since prepare() is called in create
}
catch (Exception e)
{
e.printStackTrace();
}
if (mMP != null) mMP.start();

return START_STICKY;
}


My problem is that with the call to setAudioStreamType(), the MediaPlayer never plays the audio. If I comment that line out, the audio plays.

With the line in, I get the following runtime error(s):


04-10 19:32:03.115: E/MediaPlayer(3411): setAudioStream called in state 8

04-10 19:32:03.115: E/MediaPlayer(3411): error (-38, 0)

04-10 19:32:03.115: E/MediaPlayer(3411): start called in state 0

04-10 19:32:03.115: E/MediaPlayer(3411): error (-38, 0)

04-10 19:32:03.115: E/MediaPlayer(3411): Error (-38,0)

04-10 19:32:03.115: E/MediaPlayer(3411): Error (-38,0)


Some research (I can't find the link now) told me that
setAudioStreamType()
can't be called after
prepare()
has been called, and that
create()
implicitly calls
prepare()
.

In any regard, how am I supposed to
setAudioStreamType()
without such an error?

Answer

You can either call mp.reset() and then set the stream type, data source, and then prepare. Alternately just use the default constructor and handle the initialization yourself.

EDIT:

Resources res = getResources();
AssetFileDescriptor afd = res.openRawResourceFd(R.raw.alarm);

mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_ALARM);
mp.setLooping(true);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.start();
Comments