Handling Phone Call Requests the Right Way for Users
Posted by Dirk Dougherty, Android Developer
Relations
One of the things users like most about Android is the flexibility to choose
which apps should handle common tasks on their devices — from opening a web page
or sending an SMS to playing a music file, taking a picture, or making phone
calls. This flexibility is provided by
Intents give you a powerful way to integrate your apps deeply into the system — users can even choose to let your apps replace functionality provided by system apps. In those cases, it’s essential to make sure that anything your app can’t or doesn’t handle can still be handled properly by the default system app.
Proper implementation and testing are especially important for apps that provide telephony services. Make sure that your app doesn't interfere with emergency calling by listening for the wrong intent —
When the user initiates a call, the system notifies interested apps by sending an ordered broadcast of the
If you want your phone calling app to be able to handle outgoing call requests, implement a broadcast receiver that receives the
Note that the system broadcasts
Here’s an example broadcast receiver declared in an app’s manifest file:
CALL_PRIVILEGED should only be used by apps that have the necessary
If your app includes intent filters that listen for CALL_PRIVILEGED Intents, make sure to remove those filters and related code from the app (in favor of
Intents
.Intents give you a powerful way to integrate your apps deeply into the system — users can even choose to let your apps replace functionality provided by system apps. In those cases, it’s essential to make sure that anything your app can’t or doesn’t handle can still be handled properly by the default system app.
Proper implementation and testing are especially important for apps that provide telephony services. Make sure that your app doesn't interfere with emergency calling by listening for the wrong intent —
CALL_PRIVILEGED
. Follow the best practices below to handle outgoing
calls the right way, using the NEW_OUTGOING_CALL
intent.Listening for outgoing call requests
Apps that provide phone calling services (such as VOIP or number management) can set upIntent
filters to handle outgoing call requests, such as those made from the Dialer
or other installed apps. This provides a seamless integration for the user, who
can transition directly to the calling service without having to redial or
launch another app.When the user initiates a call, the system notifies interested apps by sending an ordered broadcast of the
NEW_OUTGOING_CALL
Intent
, attaching the original phone number, URI, and other
information as extras. This gives apps such as Google Voice and others a chance
to modify, reroute, or cancel the call before it’s passed to the system’s
default phone app.If you want your phone calling app to be able to handle outgoing call requests, implement a broadcast receiver that receives the
NEW_OUTGOING_CALL
Intent
, processes the number, and initiates a call as needed. Make
sure to declare an intent filter for NEW_OUTGOING_CALL
in the
receiver, to let the system know that your app is interested in the broadcast.
You’ll also need to request the PROCESS_OUTGOING_CALLS
permission in order to receive the Intent
.Note that the system broadcasts
NEW_OUTGOING_CALL
only for
numbers that are not associated with core dialing capabilities such as
emergency numbers. This means that NEW_OUTGOING_CALL
can not
interfere with access to emergency services the way your use of
CALL_PRIVILEGED
might.Here’s an example broadcast receiver declared in an app’s manifest file:
<manifest> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> <application> ... <receiver android:name=MyOutgoingCallHandler"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </receiver> ... </application> </manifest>The implementation of the corresponding broadcast receiver would look something like this:
public class MyOutgoingCallHandler extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Extract phone number reformatted by previous receivers String phoneNumber = getResultData(); if (phoneNumber == null) { // No reformatted number, use the original phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); } // My app will bring up the call, so cancel the broadcast setResultData(null); // Start my app to bring up the call ... } }Because the
NEW_OUTGOING_CALL
broadcast is ordered, your app can
choose whether to consume the call request itself or simply process the number
and pass the result data on to other apps that may be interested. In this
example, the broadcast receiver brings up a phone call on it’s own service and
sets the result data to null. This prevents the call request from reaching the
default phone app.An anti-pattern
Rather than listening forNEW_OUTGOING_CALL
Intents, some apps
have mistakenly set up intent filters for CALL_PRIVILEGED
Intents
as a way to handle outgoing calls. This is not a recommended approach, because
the system may send a CALL_PRIVILEGED Intent
for any number,
including emergency numbers. Since non-system apps can’t reformat emergency
numbers or place emergency calls, attempting to handle
CALL_PRIVILEGED
could inadvertently interfere with access to
emergency numbers. CALL_PRIVILEGED should only be used by apps that have the necessary
signatureOrSystem
-level permission — it is not designed for use by
any third-party apps. Check your apps for proper use of NEW_OUTGOING_CALL
If your app provides phone calling services and already uses intent filters to handle outgoing call requests, take a few minutes to make sure it is listening for the proper Intent:NEW_OUTGOING_CALL
.
If your app includes intent filters that listen for CALL_PRIVILEGED Intents, make sure to remove those filters and related code from the app (in favor of
NEW_OUTGOING_CALL
) and publish the updated app as soon as possible.
No comments:
Post a Comment