我已经实现了一个从 Android 中的 URL 播放媒体的活动。
为了在来电时添加暂停功能,我创建了一个接收器,它在来电时设置一个变量。Activity 读取这个变量onPause()
,暂停音乐并重置它。当通话结束并恢复活动时,音乐将在 中恢复onResume()
。
只要活动有焦点,这就可以正常工作。如果我在播放音乐时回到主屏幕,然后来电,onPause()
则不会被调用。因此,我无法停止和开始音乐。
有没有人实现了一个媒体播放器来拦截来电/去电并正确停止/开始音乐?
我已经实现了一个从 Android 中的 URL 播放媒体的活动。
为了在来电时添加暂停功能,我创建了一个接收器,它在来电时设置一个变量。Activity 读取这个变量onPause()
,暂停音乐并重置它。当通话结束并恢复活动时,音乐将在 中恢复onResume()
。
只要活动有焦点,这就可以正常工作。如果我在播放音乐时回到主屏幕,然后来电,onPause()
则不会被调用。因此,我无法停止和开始音乐。
有没有人实现了一个媒体播放器来拦截来电/去电并正确停止/开始音乐?
您可以做几件事:
首先,您可以使用PhoneStateListener
. 您可以在 TelephonyManager 中注册监听器:
PhoneStateListener phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
//Incoming call: Pause music
} else if(state == TelephonyManager.CALL_STATE_IDLE) {
//Not in call: Play music
} else if(state == TelephonyManager.CALL_STATE_OFFHOOK) {
//A call is dialing, active or on hold
}
super.onCallStateChanged(state, incomingNumber);
}
};
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
当不再需要监听器时,请记住取消注册监听器PhoneStateListener.LISTEN_NONE
:
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
您可以做的另一件事是收听广播android.intent.action.PHONE_STATE
。它将包含额外TelephonyManager.EXTRA_STATE
内容,可为您提供有关通话的信息。看看这里的文档。
android.permission.READ_PHONE_STATE
请注意,在这两种情况下您都需要- 权限。
我认为 AudioManager 是最好和快速的解决方案。这是我的实现示例:
public class MyActivity extends Activity implements OnAudioFocusChangeListener {
private AudioManager mAudioManager;
@Override
public void onCreate(Bundle savedInstanceState) {
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
@Override
public void onDestroy(){
super.onDestroy();
...
mAudioManager.abandonAudioFocus(this);
...
}
@Override
public void onAudioFocusChange(int focusChange) {
if(focusChange<=0) {
//LOSS -> PAUSE
} else {
//GAIN -> PLAY
}
}
}
我希望它对你有帮助:-)
我认为requestAudioFocus()应该能够自动处理这种情况。您不需要明确检查呼叫状态。
Audio Focus 本质上是合作的。也就是说,应用程序应该(并且强烈鼓励)遵守音频焦点指南,但系统不会强制执行这些规则。如果应用程序即使在失去音频焦点后仍想播放响亮的音乐,系统中的任何内容都不会阻止它。然而,用户更有可能有糟糕的体验,并且更有可能卸载行为不端的应用程序。
要请求音频焦点,您必须从 AudioManager 调用 requestAudioFocus(),如下例所示:
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// could not get audio focus.
}
你可以试试广播接收器。
创建一个CallReceiver
扩展类BroadcastReceiver
。
package com.example.callreceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class CallReceiver extends BroadcastReceiver{
TelephonyManager telManager;
Context context;
@Override
public void onReceive(Context context, Intent intent) {
this.context=context;
telManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private final PhoneStateListener phoneListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
//PAUSE
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
break;
}
case TelephonyManager.CALL_STATE_IDLE: {
//PLAY
break;
}
default: { }
}
} catch (Exception ex) {
}
}
};
}
然后在manifest.xml文件中加入这一行,在 App 上注册
<receiver android:name="CallReceiver" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" >
</action>
</intent-filter>
</receiver>
对我来说,有来电时空闲状态即将到来,快速解决方法是检查广播接收器
BroadcastReceiver phonestatereceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
String state = extras.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
//pause here
}
else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
//pause here
}
else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
//play here
}
}
}
};
基于mickesource为 android Oreo+ 和 kotlin 更新。我在服务中添加了,您可以按照相同的方式进行活动或片段。
class MusicService : Service(), AudioManager.OnAudioFocusChangeListener {
var audioManager: AudioManager? = null
var audioFocusRequest:AudioFocusRequest?=null
override fun onCreate() {
super.onCreate()
setAudioFocusChangeListener()
}
private fun setAudioFocusChangeListener() {
audioManager = getSystemService(AUDIO_SERVICE) as AudioManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
audioFocusRequest=AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(this).build()
audioManager?.requestAudioFocus(audioFocusRequest!!)
} else {
@Suppress("deprecation")
audioManager?.requestAudioFocus(
this,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN
)
}
}
override fun onAudioFocusChange(focusChange: Int) {
if(focusChange<=0){
//Pause audio
}else{
//Play audio
}
}
在 Android 10 上测试了常规和什么是应用调用