You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术求助:呼出电话接通时OnReceive BroadcastReceiver未触发

解决呼出电话接通状态检测的问题

Hey there! I’ve dealt with this exact problem before, so I totally get the frustration when your BroadcastReceiver only catches call initiation and end, but not the connected state. Let’s break down why this happens and how to fix it:

Why your current setup isn’t working

Android doesn’t send a system-wide broadcast for outgoing call connection by default. The standard ACTION_NEW_OUTGOING_CALL only triggers when the call starts, and ACTION_PHONE_STATE_CHANGED will notify you when the call ends (back to CALL_STATE_IDLE), but there’s no direct broadcast for when the call actually connects. Static registered BroadcastReceivers can’t pick up this state change because it requires more granular, dynamic listening.

Step-by-step solution

We’ll combine a BroadcastReceiver to detect outgoing call initiation, then use a PhoneStateListener (dynamically registered) plus AudioManager to confirm when the call is actually connected.

1. Update your permissions

Make sure you have these in your AndroidManifest.xml (note: for Android 10+, some permissions require runtime requests):

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

2. Create the BroadcastReceiver to catch outgoing call start

This receiver will trigger when the user initiates an outgoing call, and we’ll start our state listener from here:

public class OutgoingCallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
            String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            // Start our call state listener
            CallStateMonitor.startListening(context, phoneNumber);
        }
    }
}

3. Implement the CallStateMonitor with PhoneStateListener and AudioManager

This class will dynamically listen for phone state changes and check if the call is connected via audio state:

public class CallStateMonitor extends PhoneStateListener {
    private static TelephonyManager telephonyManager;
    private static AudioManager audioManager;
    private static String targetNumber;
    private static boolean isCallConnected = false;

    public static void startListening(Context context, String phoneNumber) {
        targetNumber = phoneNumber;
        telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        // Register the listener to track call state
        telephonyManager.listen(new CallStateMonitor(), PhoneStateListener.LISTEN_CALL_STATE);
    }

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);

        switch (state) {
            case TelephonyManager.CALL_STATE_OFFHOOK:
                // This triggers when the call is initiated, but not necessarily connected
                // Add a small delay to let the audio state update, then check if call is active
                new Handler(Looper.getMainLooper()).postDelayed(() -> {
                    if (audioManager.isVoiceCallActive()) {
                        isCallConnected = true;
                        // Your logic here: the outgoing call is now connected!
                        Log.d("CallMonitor", "Outgoing call to " + targetNumber + " connected");
                    }
                }, 1000); // Adjust delay based on device performance if needed
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                // Call ended
                if (isCallConnected) {
                    Log.d("CallMonitor", "Outgoing call to " + targetNumber + " ended");
                    isCallConnected = false;
                }
                // Unregister the listener to free up resources
                telephonyManager.listen(this, PhoneStateListener.LISTEN_NONE);
                break;
        }
    }
}

4. Register the BroadcastReceiver in AndroidManifest.xml

<receiver android:name=".OutgoingCallReceiver"
          android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>

Important notes for newer Android versions

  • Android 8.0+: Static BroadcastReceivers for many system actions are restricted. If your receiver isn’t triggering, consider registering it dynamically in your Activity/Service instead, or use a foreground service if you need background listening.
  • Runtime permissions: For Android 6.0+, you’ll need to request READ_PHONE_STATE and PROCESS_OUTGOING_CALLS from the user at runtime.
  • OEM variations: Some device manufacturers modify telephony behavior, so the delay in the CALL_STATE_OFFHOOK case might need adjustment (try 500ms or 1500ms if the 1s delay doesn’t work).

Alternative fallback: AccessibilityService

If the above method isn’t reliable on certain devices, you can use an AccessibilityService to listen for call state changes. This approach is more consistent but requires the user to enable accessibility permissions for your app.

内容的提问来源于stack exchange,提问作者user5078013

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:17:28