Is your call ended on Android Phone?

Lets think, on Android phone if we want to trap end call event. How we can achieve this on Android phone?

We can achieve this by using PhoneStateListener and BroadcastReceiver.
1) Create our own BroadCastReceiver and filter it to receive android.intent.action.PHONE_STATE using IntentFilter in AndroidManifest.
2) In BroadCastReceiver‘s onReceive() method, we can listen to Phone State by registering PhoneStateListener with TelephonyManager.
3) There are three states of phone/call, viz. CALL_STATE_RINGING, CALL_STATE_OFFHOOK, CALL_STATE_IDLE.

Following are the states which it goes through in different scenarios:
1) Answering Received call

CALL_STATE_RINGING => CALL_STATE_OFFHOOK (After Answering call) => CALL_STATE_IDLE (After End call)

2) Rejecting / Not Answering (Missed) Received call


3) Dialing call

CALL_STATE_OFFHOOK (After dialing) => CALL_STATE_IDLE (After End call)

So, the trick to detect the end call event is, to check for CALL_STATE_IDLE:
1) if its immediate previous state is CALL_STATE_OFFHOOK, then its answered call which is ended.
2) if its immediate previous state is CALL_STATE_RINGING, then its missed/rejected call which is ended.


Add following permission:


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class PhoneStateBroadcastReceiver extends BroadcastReceiver {

	private static final String TAG = "PhoneStateBroadcastReceiver";
	Context mContext;
	String incoming_nr;
	private int prev_state;
	public void onReceive(Context context, Intent intent) {
		TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object
		CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
		telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager

		Bundle bundle = intent.getExtras();
		String phoneNr= bundle.getString("incoming_number");
		    Log.v(TAG, "phoneNr: "+phoneNr);
        /* Custom PhoneStateListener */
	public class CustomPhoneStateListener 
extends PhoneStateListener { private static final String TAG = "CustomPhoneStateListener"; @Override public void onCallStateChanged(int state, String incomingNumber){ if(incomingNumber!=null&&incomingNumber.length()>0) incoming_nr=incomingNumber; switch(state){ case TelephonyManager.CALL_STATE_RINGING: Log.d(TAG, "CALL_STATE_RINGING"); prev_state=state; break; case TelephonyManager.CALL_STATE_OFFHOOK: Log.d(TAG, "CALL_STATE_OFFHOOK"); prev_state=state; break; case TelephonyManager.CALL_STATE_IDLE: Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_nr); if((prev_state==TelephonyManager.CALL_STATE_OFFHOOK)){ prev_state=state; //Answered Call which is ended } if((prev_state==TelephonyManager.CALL_STATE_RINGING)){ prev_state=state; //Rejected or Missed call } break; } } } }