(Android MediaPlayer)如果MediaPlayer.create()隐式调用prepare(),我该如何调用setAudioStreamType()?

我正在编写一个Android闹钟应用程序,使用服务来播放闹钟铃声。 目前,我可以播放audio,但播放的音量可以通过closures设备的音量来消除。 因此,我想添加一个调用setAudioStreamType(AudioManager.STREAM_ALARM); 为了防止这一点。

我有以下服务的onStartCommand()函数:

 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; } 

我的问题是,通过调用setAudioStreamType(),MediaPlayer从不播放audio。 如果我评论这一行,audio播放。

随着行,我得到以下运行时错误(S):

04-10 19:32:03.115:E / MediaPlayer(3411):在状态8调用setAudioStream

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

04-10 19:32:03.115:E / MediaPlayer(3411):以状态0开始调用

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

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

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

一些研究(现在我找不到链接)告诉我,在prepare()被调用之后setAudioStreamType()不能被调用, create()隐式调用prepare()

无论如何,我该如何设置setAudioStreamType()没有这样的错误?

Solutions Collecting From Web of "(Android MediaPlayer)如果MediaPlayer.create()隐式调用prepare(),我该如何调用setAudioStreamType()?"

您可以调用mp.reset() ,然后设置streamtypes,数据源,然后进行准备。 或者只是使用默认的构造函数,并自己处理初始化。

编辑:

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

接受的答案是抛出一个IllegalStateException 。 这是工作

 MediaPlayer mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource( this, getCustomToneUri() ); mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); mediaPlayer.prepareAsync(); } catch (IOException e) { e.printStackTrace(); }