Android Broadcast Receiver监听通话时OFFHOOK触发两次导致录音重复如何解决
问题修复方案
问题根源
你遇到的CALL_STATE_OFFHOOK回调两次的问题,核心原因有两个:
- 重复注册PhoneStateListener:你将
telephonyManager.listen()的注册逻辑写在了BroadcastReceiver的onReceive()方法中,每次广播触发onReceive时都会新建一个PhoneStateListener实例注册到系统服务,注册多少个监听器就会收到多少次状态回调,自然会出现多次触发的问题。 - 缺少状态去重逻辑:即使只注册一个监听器,部分定制ROM也可能因厂商修改逻辑重复推送相同的通话状态,没有状态对比的防护就会重复触发Service。
修复步骤
- 第一步:先移除重复注册逻辑,每次注册新监听器前先注销之前的旧监听器,避免多实例同时监听
修改后的onReceive核心代码如下:
public void onReceive(Context context, Intent intent) { Intent notificationIntent = new Intent(context, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT); TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); // 新增:先注销之前注册的旧监听器,避免多实例 if (phoneStateListener != null) { telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); } telephonyManager.listen(phoneStateListener = new PhoneStateListener() { // 全局静态变量存储上一次的通话状态 private int lastCallState = TelephonyManager.CALL_STATE_IDLE; @Override public void onCallStateChanged(int state, String phoneNumber) { super.onCallStateChanged(state, phoneNumber); // 新增:相同状态直接返回,不重复处理 if (state == lastCallState) { return; } lastCallState = state; Intent intent1 = new Intent(context, AutoRecordService.class); intent1.putExtra("phoneNumber", phoneNumber); intent1.putExtra("inputExtra", "Screen rights"); switch (state){ case TelephonyManager.CALL_STATE_IDLE: intent1.setAction("IDLE"); Log.i(TAG, "onIdle: "); break; case TelephonyManager.CALL_STATE_RINGING: intent1.setAction("RINGING"); break; case TelephonyManager.CALL_STATE_OFFHOOK: intent1.setAction("OFFHOOK"); Log.i(TAG, "onOffhook: "); break; default: intent1.setAction("OUTGOINGCALL"); break; } context.startService(intent1); } }, PhoneStateListener.LISTEN_CALL_STATE); }
- 第二步:在Service侧增加双重防护,判断如果当前已经处于录音状态,收到
OFFHOOK指令时直接忽略,避免极端场景下的重复触发。
内容的提问来源于stack exchange,提问作者Sơn Nguyễn
相关产品推荐
相关产品推荐

