Incoming Phone Call Receiver - Android Broadcast ReceiverÂ
🎯 Overview Broadcast Receiver
BroadcastReceiver: In Android, a BroadcastReceiver is a component that responds to broadcast messages sent by the system or other applications. It allows an application to receive and react to system-wide events, such as incoming phone calls, network changes, or battery low notifications. By extending the BroadcastReceiver class, we can override the onReceive() method to define custom behavior when a broadcast message is received.
Phone State: The telephony service in Android provides access to information related to phone calls. The call state represents the current state of a phone call, which can be one of the following states:
CALL_STATE_IDLE: No activity, no calls.
CALL_STATE_RINGING: A new incoming call is ringing or waiting.
CALL_STATE_OFFHOOK: At least one call is in progress (active, on hold, or dialing).
TelephonyManager: The TelephonyManager class provides access to telephony-related information and services on the device. It allows retrieving information such as the SIM card state, device's phone number, network operator, and call-related events. In the code, TelephonyManager is used to listen for changes in the call state by registering a PhoneStateListener.
IntentFilter: An IntentFilter is used to declare what types of intents an application component, such as a BroadcastReceiver, can receive. It specifies the types of intents an application is interested in by adding actions, categories, and data schemes to the filter. In the code, an IntentFilter is created with the ACTION_PHONE_STATE_CHANGED action to filter incoming phone state change intents.
Manifest Declaration: To register a BroadcastReceiver in an Android application, it must be declared in the manifest file. In the provided code, the MyReceiver class is declared as a receiver in the manifest using the <receiver> tag. The <intent-filter> tag inside the receiver element specifies that the receiver should listen for the ACTION_PHONE_STATE_CHANGED action.
Permissions: Android applications require certain permissions to access sensitive information or perform specific actions. In this case, the code includes two permissions:
🎯 Broadcast Receiver Source Code
public class MyReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(final Context context, Intent intent) {
            Log.i("MyReceiver", "call state changed.... ");
//Tracking 2nd sim Mobile number
            String second_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String second_number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            Log.i("MyReceiver", "call state changed.... "+second_number);
            Log.i("MyReceiver", "call state changed.... "+second_state);
            TelephonyManager mtelephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
            mtelephony.listen(new PhoneStateListener(){
                @Override
                public void onCallStateChanged(int state, String incomingNumber) {
                    Log.i("MyReceiver", "call state changed.... "+state);
                    super.onCallStateChanged(state, incomingNumber);
                    switch (state) {
                        case TelephonyManager.CALL_STATE_RINGING:
                            Log.d("MyReceiver", "I'm in " + state + " and the number is " + incomingNumber);
                            break;
                        default:
                            break;
                    }
                }
            },PhoneStateListener.LISTEN_CALL_STATE);
        }
}
🎯 How Code Works?
The code consists of a BroadcastReceiver called MyReceiver that is responsible for receiving and handling incoming phone call events. When an incoming call is received, the onReceive() method of the MyReceiver class is triggered. The onReceive() method is overridden to provide custom behavior when a phone call state changes.
Inside the onReceive() method, the code logs a message indicating that the call state has changed. It then retrieves the second SIM's mobile number and the call state from the received intent using the TelephonyManager.EXTRA_INCOMING_NUMBER and TelephonyManager.EXTRA_STATE extras, respectively.
After logging the call state and number, the code creates an instance of TelephonyManager to access telephony-related information and registers a PhoneStateListener to listen for changes in the call state.
Inside the PhoneStateListener's onCallStateChanged() method, the code logs the updated call state and the incoming phone number when the call state is CALL_STATE_RINGING. This allows tracking of the phone call's state and associated number.
The code also includes the necessary setup in the activity and manifest files to register the MyReceiver class as a receiver for the ACTION_PHONE_STATE_CHANGED intent.
🎯 From Activity
MyReceiver myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(myReceiver, intentFilter);
🎯 Manifest.XML
<receiver android:name=".MyReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
</receiver>
🎯 Permissions
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>