Here is a very good answer.
See link below
Click here
When you see the above example, you will learn how to get the final state of the call, and you will also keep in mind that after the call is completed, CALL_STATE_IDLE will call more than once, so you need to take one static variable at any point where you need to check this variable value before you start working in perfect condition.
EDIT
Android stores call log information in an embedded database. So much the better solution is that when your code calls IDLE after the OFFHOOK state, then you can copy the whole new call log from the built-in database to your database to get information about the call log
You can get call log information from the embedded database using the following query
Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, null, null, null, null);
EDIT2
Here is a complete example
This is the PhoneStateListener class
public class CustomPhoneStateListener extends PhoneStateListener { Context context; public CustomPhoneStateListener(Context context) { super(); this.context = context; } @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch (state) { case TelephonyManager.CALL_STATE_IDLE: // Toast.makeText(context, "CALL_STATE_IDLE", Toast.LENGTH_LONG).show(); if(UDF.phoneState != TelephonyManager.CALL_STATE_IDLE) { UDF.fetchNewCallLogs(context); } break; case TelephonyManager.CALL_STATE_OFFHOOK: //Toast.makeText(context, "CALL_STATE_OFFHOOK", Toast.LENGTH_LONG).show(); break; case TelephonyManager.CALL_STATE_RINGING: //Toast.makeText(context, "CALL_STATE_RINGING", Toast.LENGTH_LONG).show(); endCallIfBlocked(incomingNumber); break; default: break; } UDF.phoneState = state; }
This is the broadcast receiver class.
public class PhoneStateBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //UDF.createTablesIfNotExists(context); TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); telephonyManager.listen(new CustomPhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE); } }
This is a function for getting new call logs from the internal database.
public static void fetchNewCallLogs(Context context) { CallLogHelper callLogHelper = new CallLogHelper(context); callLogHelper.open(); Long maxId = callLogHelper.getMaxId(); Cursor c = context.getContentResolver().query(android.provider.CallLog.Calls.CONTENT_URI, null, "_id > ?", new String[]{String.valueOf(maxId)}, null); if(c != null && c.moveToFirst()) { while (c.isAfterLast() == false) { int _ID = c.getColumnIndex(android.provider.CallLog.Calls._ID); int _NUMBER = c.getColumnIndex(android.provider.CallLog.Calls.NUMBER); int _DATE = c.getColumnIndex(android.provider.CallLog.Calls.DATE); int _DURATION = c.getColumnIndex(android.provider.CallLog.Calls.DURATION); int _CALLTYPE = c.getColumnIndex(android.provider.CallLog.Calls.TYPE); int _NAME = c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME); int _NUMBERTYPE = c.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE); int _NEW = c.getColumnIndex(android.provider.CallLog.Calls.NEW); String id = c.getString(_ID); String number = c.getString(_NUMBER); String date = c.getString(_DATE); String duration = c.getString(_DURATION); String callType = c.getString(_CALLTYPE); String name = c.getString(_NAME); String numberType = c.getString(_NUMBERTYPE); String _new = c.getString(_NEW); callLogHelper.createLog(id, number, date, duration, callType, name, numberType, _new, "N"); c.moveToNext(); } } callLogHelper.close(); } **Where** => CallLogHelper is a helper class to communicate with my local database => callLogHelper.getMaxId(); will returns the maximum id of call logs in my local database and I am keeping the id in local database and internal database will be same => callLogHelper.createLog() is my function to insert call log in my local database
This is the manifest file
<receiver android:name=".PhoneStateBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE"/> </intent-filter> </receiver>