Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art
Doing Something When the Phone RingsBack to Android Cookbook Home | Up to Chapter: Telephone Applications

Author: Johan Pelgrim ('jpelgrim')
In Published Edition? Yes
FormatLanguage: WikiFormat

Doing Something When the Phone Rings


You want to act on an incoming phone call and do something with the incoming number.


This can be achieved by implementing a Broadcast receiver and listening for a TelephonyManager.ACTION_PHONE_STATE_CHANGED action.


If you want to do something when the phone rings you have to implement a broadcast receiver which listens for the TelephonyManager.ACTION_PHONE_STATE_CHANGED intent action. This is a broadcast intent action indicating that the call state (cellular) on the device has changed.

1. Create a class IncomingCallInterceptor which extends BroadcastReceiver.

2. Override the onReceive method to handle incoming broadcast messages.

3. The EXTRA_STATE intent extra in this case indicates the new call state.

4. If (and only if) the new state is RINGING, a second intent extra EXTRA_INCOMING_NUMBER provides the incoming phone number as a String.

5. We extract the number information from the EXTRA_INCOMING_NUMBER intent extra.

Note: Additionally you can act on a state change to OFFHOOK or IDLE when the user picks up the phone or ends/rejects the phone call respectively.

package nl.codestone.cookbook.incomingcallinterceptor;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.widget.Toast;

public class IncomingCallInterceptor extends BroadcastReceiver {                                    // 1

    public void onReceive(Context context, Intent intent) {                                         // 2
        String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);                         // 3
        String msg = "Phone state changed to " + state;
        if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) {                                   // 4
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);  // 5
            msg += ". Incoming number is " + incomingNumber;
            // TODO This would be a good place to "Do something when the phone rings" ;-)
        Toast.makeText(context, msg, Toast.LENGTH_LONG).show();



6. We have to register our IncomingCallInterceptor as a <receiver> within the <application> element in the AndroidManifest.xml file.

7. We register an <intent-filter> ...

8. and an <action value which registers our receiver to listen for TelephonyManager.ACTION_PHONE_STATE_CHANGED broadcast messages.

9. Finally we have to register a <uses-permission> so we are allowed to listen to phone state changes.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    <uses-sdk android:minSdkVersion="3" />

    <application android:icon="@drawable/icon" android:label="Incoming Call Interceptor">

        <receiver android:name="IncomingCallInterceptor">                     // 6
            <intent-filter>                                                   // 7
                 <action android:name="android.intent.action.PHONE_STATE"/>   // 8


    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>     // 9

If all is well you should see something like this when the phone rings:

What happens if two receivers listen for phone state changes?

In general, a broadcast message is just that, a message which is sent out to many receivers at the same time. This is the case for normal broadcast messages which is used to send out the ACTION_PHONE_STATE_CHANGED intent as well. All receivers of the broadcast are run in an undefined order, often at the same time and for that reason order is not applicable.

In other cases the system sends out ordered broadcast which is described in more detail in the Recipe Process outgoing calls.

Final notes

When your BroadcastReceiver does not finish within 10 seconds the Android framework will show the infamous Application Not Responding (ANR) dialog, giving your users the possibility to kill your program. If you need to do some processing which takes longer than 10 seconds implement a Service and call the service method.

It is also not advised to start an activity from a BroadcastReceiver, as it will spawn a new screen that will steal focus from whatever application the user is currently has running. If your application has something to show the user in response to an Intent broadcast, it should do so using the Notification Manager.

See Also

Recipe Process outgoing calls http://developer.android.com/reference/android/content/BroadcastReceiver.html http://developer.android.com/reference/android/telephony/TelephonyManager.html#ACTION_PHONE_STATE_CHANGED



The source code for this project is in the Android Cookbook repository, http://github.com/IanDarwin/Android-Cookbook-Examples/tree/master/TelephonyManager