Android仿虾米音乐播放器之电话和耳机监听

时间:2022-05-02 06:59:52

     任何一个用户都不会希望在电话打来时,音乐依然在播放,这样或许用户马上就卸载了我们的app,另外当用户的耳机拨出时我们需要及时的停止音乐,因为拨出耳机这个动作可能不是用户主导的,或许是耳机的松动,或许是不小心,如果耳机拨出后音乐继续播放,也可能会带来不必要的麻烦。

   先说电话监听,Android其实并没有真正的来电监听的Action,只有一个读取电话的状态,以及一个呼出状态的Action,但是我们有了这两个就可以监听来电了,毕竟不是呼出的事件就是来电了,所以我们可以这样写,首先需要加入权限

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

我们单独创立一个广播类来接收这个信息,采用静态注册的方式

<receiver android:name="com.sheepm.broadcast.PhoneBroadcastReceiver">
		    <intent-filter>
		        <action android:name="android.intent.action.PHONE_STATE"/>
		        <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
		    </intent-filter>
		</receiver>
判断action如果不是ACTION_NEW_OUTGOING_CALL,那么便是来电了,因为没有设置为挂断时自动重新播放歌曲,所以下面的监听事件就没有写,可以在TelephonyManager.CALL_STATE_IDLE中加入播放的广播
public class PhoneBroadcastReceiver extends BroadcastReceiver {

	private String TAG = "PhoneBroadcastReceiver";

	/**
	 * 之所以判断音乐是否播放,是因为如果只是打开界面而没播放,会报一个错误 sending message to a Handler on a dead
	 * thread
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
			Log.i("---拨出电话", "拨出电话");
			if (Myapp.isPlay) {
				Message msg = Message.obtain();
				msg.obj = context;
				handler.sendMessage(msg);
			}
		} else {
			if (Myapp.isPlay) {
				Message msg = Message.obtain();
				msg.obj = context;
				handler.sendMessage(msg);
			}
			// 来电监听
			TelephonyManager tManager = (TelephonyManager) context
					.getSystemService(Service.TELEPHONY_SERVICE);
			tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
		}

	}

	/**
	 * 电话状态监听
	 */
	PhoneStateListener listener = new PhoneStateListener() {

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			super.onCallStateChanged(state, incomingNumber);
			switch (state) {
			// 挂断
			case TelephonyManager.CALL_STATE_IDLE:
				break;

			//接听
			case TelephonyManager.CALL_STATE_OFFHOOK:

				break;
			//来电
			case TelephonyManager.CALL_STATE_RINGING:

				break;

			default:
				break;
			}
		}

	};

	Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			Context context = (Context) msg.obj;
			Intent phonepause = new Intent();
			phonepause.setAction(Constants.ACTION_PAUSE);
			context.sendBroadcast(phonepause);
		}

	};

}
    然后就是耳机监听了,偷懒直接写在了service里面,一开始用的耳机的Action是 android.intent.action.HEADSET_PLUG,后来发现这个有一个bug,那就是在耳机拨出后有1秒左右的延迟,体验十分不好,后来发现了一个实时的一个ACTION,AudioManager.ACTION_AUDIO_BECOMING_NOISY

if (intent.getAction().equals(
					AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
				isPlaying = false;
				//如果耳机拨出时暂停播放
					if (intent.getIntExtra("state", 0) == 0 ) {
						Intent intent2 = new Intent();
						intent2.setAction(Constants.ACTION_PAUSE);
						sendBroadcast(intent2);
					}

			}