Cannot detect when outgoing call is answered in Android
android, broadcastreceiver
Solution
Since Android 5.0 this is possible for system apps. But you need to use the hidden Android API.
I got it to work like this:
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
<receiver android:name=".listener.OutCallLogger">
<intent-filter>
<action android:name="android.intent.action.PRECISE_CALL_STATE" />
</intent-filter>
</receiver>
public class OutCallLogger extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getIntExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, -2) {
case PreciseCallState.PRECISE_CALL_STATE_IDLE:
Log.d(This.LOG_TAG, "IDLE");
break;
case PreciseCallState.PRECISE_CALL_STATE_DIALING:
Log.d(This.LOG_TAG, "DIALING");
break;
case PreciseCallState.PRECISE_CALL_STATE_ALERTING:
Log.d(This.LOG_TAG, "ALERTING");
break;
case PreciseCallState.PRECISE_CALL_STATE_ACTIVE:
Log.d(This.LOG_TAG, "ACTIVE");
break;
}
}
}
You can find all possible call states in PreciseCallState.java and all extras that the intent contains in TelephonyRegistry.java.
Problem
To detect when an outgoing call is answered, I tried creating a `PhoneStateListener` and listening for `TelephonyManager`'s `CALL_STATE_RINGING`, `CALL_STATE_OFFHOOK`, and `CALL_STATE_IDLE`, from this question, but it does not seem to work, as explained below. First, I registered the following permission in the manifest: ``` <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> ``` Then, a `BroadcastReceiver` called `OutCallLogger` that catches the `NEW_OUTGOING_CALL` event whenever an outgoing call is made: ``` <receiver android:name=".listener.OutCallLogger"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> ``` Next, my implementation of `OutCallLogger`. I set up a boolean called `noCallListenerYet` to avoid attaching a new `PhoneStateListener` to the `TelephonyManager` whenever `onReceive()` is invoked. ``` public class OutCallLogger extends BroadcastReceiver { private static boolean noCallListenerYet = true; @Override public void onReceive(final Context context, Intent intent) { number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); if (noCallListenerYet) { final TelephonyManager tm = (TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE); tm.listen(new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING: Log.d(This.LOG_TAG, "RINGING"); break; case TelephonyManager.CALL_STATE_OFFHOOK: Log.d(This.LOG_TAG, "OFFHOOK"); break; case TelephonyManager.CALL_STATE_IDLE: Log.d(This.LOG_TAG, "IDLE"); break; default: Log.d(This.LOG_TAG, "Default: " + state); break; } } }, PhoneStateListener.LISTEN_CALL_STATE); noCallListenerYet = false; } } } ``` Now, when I make an outgoing call in my device, `CALL_STATE_RINGING` is NEVER invoked. I always only get printouts of "IDLE" to "OFFHOOK" when the other line starts ringing, nothing when the call is answered, and a printout of "IDLE" again when the call is ended. How can I reliably detect when an outgoing call is answered in Android, or is that even possible?