Android:MediaPlayer AUDIOFOCUS_LOSS和setOnErrorListener()问题

我正在创建一个音乐播放器应用程序。

在那我正在检查我的应用程序是否失去AudioFocus然后播放将停止。 但这引发了一个问题,当我播放一首曲目 – 然后停止它 – 然后再次播放曲目时, switch case AudioManager.AUDIOFOCUS_LOSS正在调用,其中我已经停止播放器,因为它正在失去焦点。

所以我自己的应用正在失去对自己的关注。 显然,这些不是我的意图。 当其他一些音乐播放器请求关注时我希望它被调用。

 private OnAudioFocusChangeListener focusChangeListener = new OnAudioFocusChangeListener() { @Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_LOSS: if (mPlayer.isPlaying()) { stopPlayback(); } break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: if (mPlayer.isPlaying()) { mPlayer.pause(); } break; case AudioManager.AUDIOFOCUS_GAIN: if (!mPlayer.isPlaying()) { initiatePlayback(); } break; } } }; 

还有一个问题 ,我得到的exception是IllegalStateException

这意味着当代码到达case AudioManager.AUDIOFOCUS_LOSS ,我的音乐播放器处于某种错误状态。 所以要检查一下,我使用以下命令注册了一个OnErrorListener

 //Inside Service - onCreate() Method mPlayer.setOnErrorListener(mErrorListener); 

但这个监听器永远不会被调用。 我会提供任何帮助。

我有类似的问题,我强烈怀疑你的focusChangeListener是在你的程序中的某个地方重新创建的,所以你请求专注于focusChangeListener不同实例。 您是从服务或活动中定义它吗?

我们的想法是维护您传递给requestAudioFocus()abandonAudioFocus() focusChangeListener 的单个副本 ; 否则AudioManager会考虑来自不同来源的请求,这可能会导致应用程序失去焦点。

您应该知道在同一个侦听器对象上多次调用requestAudioFocus() 只会注册一次,并且一次调用abandonAudioFocus()就足以释放音频焦点。

很少有建议可以解决您的问题:

  • 尝试将focusChangeListener定义为静态对象,并查看是否有帮助。

  • 如果您的侦听器已在Activity中注册,请考虑转移到服务,以便侦听器可以存活更长时间。

  • 要调试此问题,每当**请求或放弃焦点以确保您拥有时,记录以下**非常有帮助,以确保您正在处理同一个实例:

    • 你的focusChangeListener,例如focusChangeListener.hashCode()
    • 当前上下文对象,例如context.hashCode()
    • 当前线程ID,例如Thread.currentThread().getId()

例如:

  Log.d(TAG, String.format("Request audio focus: thread id = %s, context = %s, listener = %s",Thread.currentThread().getId(),context.hashCode(),focusChangeListener hashCode()) 

编辑:

使用应用程序上下文即getApplicationContext()也可以解决问题。

不幸的是,IllegalStateExceptions不会触发OnErrorListener调用。 您将不得不尝试/捕获代码的部分代码以用于可能触发它们的IllegalStateExceptions。