Android中InCallService检测未接通通话时的振铃来电问题
解决InCallService振铃状态下无法检测新来电的问题
当应用已有一通振铃未接通的通话时,新来电不会触发onCallAdded(),这是因为系统将这类通话视为并发通话,不会单独触发单次添加回调。可以通过以下方式解决:
1. 重写onCallsChanged()方法
这个方法会在系统通话列表发生变化时触发(包括新增并发来电),遍历所有通话即可检测到新的振铃通话:
@Override public void onCallsChanged(List<Call> calls) { super.onCallsChanged(calls); for (Call call : calls) { // 筛选出处于振铃状态且未激活的通话 if (call.getState() == Call.STATE_RINGING && !call.isActive()) { handleNewRingingCall(call); } } }
2. 给每个Call注册状态监听器
在onCallAdded()中为通话注册Call.Callback,监听状态变化,即使是并发来电的状态更新也能捕获:
private Call.Callback mCallCallback; @Override public void onCreate() { super.onCreate(); mCallCallback = new Call.Callback() { @Override public void onStateChanged(Call call, int state) { super.onStateChanged(call, state); if (state == Call.STATE_RINGING) { handleNewRingingCall(call); } } }; } @RequiresApi(api = Build.VERSION_CODES.Q) @Override public void onCallAdded(Call call) { super.onCallAdded(call); call.registerCallback(mCallCallback); // 处理初始添加的振铃通话 if (call.getState() == Call.STATE_RINGING) { handleNewRingingCall(call); } } @Override public void onCallRemoved(Call call) { super.onCallRemoved(call); call.unregisterCallback(mCallCallback); // 避免内存泄漏 }
3. 统一处理逻辑
封装handleNewRingingCall()方法,复用新来电的处理逻辑:
@RequiresApi(api = Build.VERSION_CODES.Q) private void handleNewRingingCall(Call call) { String number = Objects.requireNonNull(call.getDetails().getHandle()).getSchemeSpecificPart(); int callType = call.getDetails().getCallDirection(); // 这里添加你的来电UI展示、逻辑处理代码 }
注意事项
- 确保Manifest中
CallService的配置正确,特别是BIND_INCALL_SERVICE权限和IN_CALL_SERVICE_UI元数据:<service android:name=".services.CallService" android:enabled="true" android:exported="true" android:permission="android.permission.BIND_INCALL_SERVICE"> <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" /> <intent-filter> <action android:name="android.telecom.InCallService" /> </intent-filter> </service> - Android 10及以上需要申请
READ_PHONE_STATE权限,确保动态权限已获取。
内容的提问来源于stack exchange,提问作者Saify
相关产品推荐
相关产品推荐

