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:

package com.mobisys.android.salesbooster;

import com.mobisys.android.salesbooster.database.HelperDatabase;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
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; } } } }
AUTHOR: Mahavir Jain

Founder @CodeToArt, Leads Android Development at CodeToArt.

  • Dude

    Any way we can get the state of an outgoing call that is answered? I cant figure it out?

    March 19, 2012
  • Stopos


    I can fix that, or you can share the class…

    NumberDatabase database=new NumberDatabase(mContext);

    – NumberDatabase cannot be resolved to a type


    August 6, 2013
  • Sandip Limbachiya

    Thank you sir for replay me on , its really helpfully.

    July 23, 2014
  • anmol

    what if a call is came , i didn’t pickup and it ended. So how to check call end in that case??

    March 4, 2015

Leave a Comment

Your email address will not be published.