Android. How to identify an outgoing call? An answer or an answer received?

Is there a way to detect an outgoing call that was successfully received or answered? I am using Intent.ACTION_CALL to dial the call and PhoneCallListener to find the call state when the outgoing call was answered, but I could not achieve this. Is this possible in android?

+3


source to share


3 answers


After deep work on this issue, I came to this conclusion:

  • PhoneStateListener won't work for outgoing calls, it calls OFFHOOK instead of RINGING, and OFFHOOK is never called in ANSWER.
  • By using NotificationListenerService, you can listen for sent notifications associated with outgoing calls. You can do something like the code below. The problem here is that I was unable to receive the notification text from some Samsung phones , and the text itself can change a lot from one phone to another. API 18 or higher is also required .

    public class NotificationListener extends NotificationListenerService {
    private String TAG = this.getClass().getSimpleName();
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
    Log.i(TAG, "Notification Posted");
    Log.i(TAG, sbn.getPackageName() +
            "\t" + sbn.getNotification().tickerText + 
            "\t" + sbn.getNotification().extras.getString(Notification.EXTRA_TEXT);
    
    Bundle extras = sbn.getNotification().extras;
    
    if ("Ongoing call".equals(extras.getString(Notification.EXTRA_TEXT)))
        startService(new Intent(this, ZajilService.class).setAction(ZajilService.ACTION_CALL_ANSWERED));
    else if ("Dialing".equals(extras.getString(Notification.EXTRA_TEXT)))
        startService(new Intent(this, ZajilService.class).setAction(ZajilService.ACTION_CALL_DIALING));
    }
    
    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
    Log.i(TAG, "********** onNotificationRemoved");
    Log.i(TAG, "ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText + "\t" + sbn.getPackageName());
    }
    }
    
          

  • Using AccessibilityService it is simpler than NotificationListenerService and I think it is supported by all APIs. But also using the AccessibilityService, some phones do not post useful events when "Answer" is called. On most phones, the event will be raised after answering the call with the duration of the call; Its printout looks like this:

onAccessibilityEvent EventType: TYPE_WINDOW_CONTENT_CHANGED; EventTime: 21715433; PackageName: com.android.incallui; MovementGranularity: 0; Action: 0 [ClassName: android.widget.TextView; Text: []; ContentDescription: 0 minutes 0 seconds; onAccessibilityEvent EventType: TYPE_WINDOW_CONTENT_CHANGED; EventTime: 21715533; PackageName: com.android.incallui; MovementGranularity: 0; Action: 0 [ClassName: android.widget.TextView; Text: []; ContentDescription: 0 minutes 1 seconds;



  1. API 23 has a new Call class . it has more detailed call states; State_Active. You can replace the default InCallUI of the phone with your own custom UI via InCallService I haven't tried this yet, but anyway, it's only limited to API 23, Marshmallow.

As a conclusion, you need to put together a solution combined NotificationListener and AccessibilityService to cover the whole phone, unfortunately.

+4


source


I know this has been a while, but I hope to be of service to those who are still looking for a solution!

I recently had to work on a similar project where I needed to capture the call state of an outgoing call and the only way I could find was to use a hidden Api from the native set. This is only possible for android> 5.0 due to api changes. This was tested on Android 5.0.1 and worked like a charm. (ps you need an rooted device for it to work because you need to install the app as a system app (google like!) which can then detect outgoing call states)

For recording, the PhoneStateListener does not work for detecting outgoing call states as stated in many messages.

First add this permission to your manifest file,



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

Then define that you are broadcasting, (here's some sample code!)

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;

public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, final Intent intent)
    {
        switch (intent.getIntExtra("foreground_state", -2)) {
            case 0: //  PreciseCallState.PRECISE_CALL_STATE_IDLE:
                System.out.println("IDLE");
                break;
            case 3: //  PreciseCallState.PRECISE_CALL_STATE_DIALING:
                System.out.println("DIALING");
                break;
            case 4: //  PreciseCallState.PRECISE_CALL_STATE_ALERTING:
                System.out.println("ALERTING");
                break;
            case 1: //  PreciseCallState.PRECISE_CALL_STATE_ACTIVE:
                System.out.println("ACTIVE");
                break;
        }

    }
} 

      

I replaced some of the constants with my own values ​​because I saw a lot of confusion among people unfamiliar with the concept of reflection (so for ease of reference). Alert is basically a condition where the receiver actually rings! and this does not include the call setup time, which means the call was successfully answered !. There are other options in the exact_call_state class (which I didn't study) to help you answer the call!

0


source


You need to use a combination of state RINGING

and OFFHOOK

to find out if the call is answered.

See this thread for the actual code on how to achieve this.

-1


source







All Articles