Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept outgoing calls on hangup

Tags:

android

We want to intercept the outgoing call hangup state in a broadcast receiver. We are listening to android.intent.action.PHONE_STATE and do get notified on IDLE state, that is when the call finishes.

Unfortunately, we do not get the called number from the call log content provider. It always returns the last call. Interestingly the incoming call do send a number in the intent but nothing for outgoing call.

If we use android.intent.action.NEW_OUTGOING_CALL, the phone number is coming through the intent when the call starts, but this stage is too early for us to do any processing as we want to wait for the call to complete.

public class InterceptOutgoingCall extends BroadcastReceiver {
Boolean isOutGoingCall = true;
private static final String LOG_TAG = "InterceptOutgoingCall";

@Override
public void onReceive(Context context, Intent intent) {

    //1. Logging the intent params

    String state = null;
    StringBuffer buf = new StringBuffer();
    if (intent.getAction() != null)
        buf.append("Intent action: " + intent.getAction());
    if (intent.getCategories() != null) {
        Set<String> categories = intent.getCategories();
        if (categories != null) {
            Iterator<String> it = categories.iterator();
            buf.append("; categories: ");
            int ctr = 0;
            for (; it.hasNext();) {
                String category = (String) it.next();
                if (ctr != 0)
                    buf.append("/");
                buf.append(category);
                ++ctr;
            }
        }
    }
    if (intent.getData() != null) {
        buf.append("; intent data: " + intent.getData().toString());
    }
    Bundle extras = intent.getExtras();
    if (extras != null) {
        buf.append("; extras: ");
        int ctr = 0;

        Set keys = extras.keySet();
        for (Iterator it = keys.iterator(); it.hasNext();) {
            String key = (String) it.next();
            Object value = extras.get(key);
            if (ctr != 0)
                buf.append("/");
            String strvalue = value == null ? "null" : value.toString();
            if (key.equals("state"))
                state = strvalue;
            buf.append(key + "=" + strvalue);
            ++ctr;
        }
        Log.i(LOG_TAG, buf.toString());
        if ("IDLE".equals(state)) {
            Log.i(LOG_TAG, "Number of the other party: "
                    + getLastCallLogEntry(context));
        }
    }

        String outgoingCall = CallLog.Calls.getLastOutgoingCall(context);
        Log.i(LOG_TAG, "Last call:" + outgoingCall);


}

private String getLastCallLogEntry(Context context) {
    String[] projection = new String[] { BaseColumns._ID,
            CallLog.Calls.NUMBER, CallLog.Calls.TYPE };
    ContentResolver resolver = context.getContentResolver();
    Cursor cur = resolver.query(CallLog.Calls.CONTENT_URI, projection,
            null, null, CallLog.Calls.DEFAULT_SORT_ORDER);
    int numberColumn = cur.getColumnIndex(CallLog.Calls.NUMBER);
    int typeColumn = cur.getColumnIndex(CallLog.Calls.TYPE);
    if (!cur.moveToNext()) {
        cur.close();
        return "";
    }
    String number = cur.getString(numberColumn);
    String type = cur.getString(typeColumn);
    String dir = null;
    try {
        int dircode = Integer.parseInt(type);
        switch (dircode) {
        case CallLog.Calls.OUTGOING_TYPE:
            dir = "OUTGOING";
            break;

        case CallLog.Calls.INCOMING_TYPE:
            dir = "INCOMING";
            break;

        case CallLog.Calls.MISSED_TYPE:
            dir = "MISSED";
            break;
        }
    } catch (NumberFormatException ex) {
    }
    if (dir == null)
        dir = "Unknown, code: " + type;
    cur.close();
    return dir + "," + number;
}

Log cat

*When call starts, NEW_OUTGOING_CALL is broadcast*

04-27 13:07:16.756: INFO/InterceptOutgoingCall(775): Intent action: android.intent.action.NEW_OUTGOING_CALL; extras: android.phone.extra.ALREADY_CALLED=false/android.intent.extra.PHONE_NUMBER=999222/android.phone.extra.ORIGINAL_URI=tel:999-222

Result data

04-27 13:07:16.876: INFO/InterceptOutgoingCall(775): Result Data:999222

Call Logs last call

04-27 13:07:17.156: INFO/InterceptOutgoingCall(775): Last call:809090

*Next, PHONE_STATE is broadcast, No number in extras*

04-27 13:07:19.495: INFO/InterceptOutgoingCall(775): Intent action: android.intent.action.PHONE_STATE; extras: state=OFFHOOK

No Result Data

04-27 13:07:19.636: INFO/InterceptOutgoingCall(775): No result data

When call is complete, No number in extras

04-27 13:08:09.306: INFO/InterceptOutgoingCall(775): Intent action: android.intent.action.PHONE_STATE; extras: state=IDLE

Call log last entry is the previously called number

04-27 13:08:09.627: INFO/InterceptOutgoingCall(775): Number of the other party: OUTGOING,809090
04-27 13:08:09.675: INFO/InterceptOutgoingCall(775): No result data
04-27 13:08:10.336: INFO/InterceptOutgoingCall(775): Last call:809090
like image 555
Pinakin Shah Avatar asked Apr 27 '11 07:04

Pinakin Shah


People also ask

How do you lock an outgoing call?

Navigate to Restrictions -> Phone. Under Calls, find the Outgoing calls option and click on Restrict to block outgoing calls on Android devices.

Can phone call be intercepted?

Cell phone spying software allows a person to gain complete access to your cell phone, including your positioning, text messages, emails and phone conversations. The intruder may even be able to turn on your microphone and listen to your conversations while you are not using the phone.

What does outgoing mean on call log?

If you see an outgoing call on your phone, it means that the call was placed from your phone. It doesn't mean that the other person hung up; it just means that the call was originated from your phone. If the person hung up, it will show up as a cancelled call on your phone and missed call on their phone.

What does it mean when the phone doesn't ring and hangs up?

The Phone Call is Going Straight to Voicemail If this happens, it's usually for one of three reasons: The phone is not on – either the battery died or the person has turned their phone off. The phone is in airplane mode – Airplane mode is a function the phone's owner will use to disconnect it from the service.


1 Answers

Use a broadcast listener with an intent android.intent.action.NEW_OUTGOING_CALL string parametrer for the IntentFilter and don't forget to give permission in AndroidMenifest to PROCESS_OUTGOING_CALLS. This will work.

public static final String outgoing = "android.intent.action.NEW_OUTGOING_CALL" ;
IntentFilter intentFilter = new IntentFilter(outgoing);
BroadcastReceiver OutGoingCallReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // TODO Auto-generated method stub
        String outgoingno = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
        Toast.makeText(context, "outgoingnum =" + outgoingno,Toast.LENGTH_LONG).show();
    }
};
registerReceiver(brForOutgoingCall, intentFilter);
like image 124
ekp Avatar answered Sep 30 '22 17:09

ekp