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?
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();