Since API 21, Google has been adding features to android.telecom in general, especially by implementing more members of TelecomManager and the addition of InCallService. This last one is is supposed to allow non-system, 3rd-party apps to provide and replace the functionality of the system Calls app in-call screen - the Window that pops up and allows action on EXTRA_STATE_OFFHOOK
or EXTRA_STATE_RINGING
broadcasts (i.e. incoming and outgoing phone calls).
Currently, only this screen has full control of ringing and active calls and associated system callbacks with fine-grained information, by means of the root-restricted MODIFY_PHONE_STATE
permission and a lot of secured AOSP code not even accessible by reflection. It's notably one of the most changed pieces of code in different manufacturers' ROM flavours, together with the launcher, contacts and camera.
This is all very pretty but...
How do you actually develop a 3rd-party InCallService?
Namely:
I won't ask answers for all of these at once, but any one answer probably associates to the other questions. This is broad but intrinsically it needs to be: there's no example on the web I've stumbled upon other than AOSP-code, and that code is based on the assumption of root-privileges, which makes it unusable for 3rd-party app development purposes.
You must keep DND mode disabled to successfully receive incoming calls on your phone. Launch Settings on your Android phone. Head into Sounds & Vibration > Do Not Disturb in the Settings menu. Turn off the Do Not Disturb toggle.
To have Call Answer take messages when your line is busy: Dial * 90 to turn it on. Dial * 91 to turn it off.
The Android Telecom framework (also known simply as "Telecom") manages audio and video calls on an Android device. This includes SIM-based calls, such as calls that use the telephony framework, and VoIP calls that implement the ConnectionService API.
First, the user will need to select your app as the default Phone app. Refer to Replacing default Phone app on Android 6 and 7 with InCallService for a way to do that.
You also need to define an InCallService
implementation the system will bind to and notify you about the call:
<service
android:name=".CallService"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService" />
</intent-filter>
</service>
There you should handle at least onCallAdded
(set up listeners on Call
, start your UI - activity - for the call) and onCallRemoved
(remove listeners).
If the user wants to answer the call, you need to invoke the method Call#answer(int)
with VideoProfile.STATE_AUDIO_ONLY
for example.
Check out Call.Callback
for events that can happen with a single call.
I don't know about Google, but you can check out my simplified example https://github.com/arekolek/simple-phone
Follow the advice from the second comment of Replacing in call app. In addition you need a service that implements the InCallService interface. When a call arrives the onCallAdded(Call call) method will be called, giving you a reference to the call object.
<service
android:name=".InCallServiceImplementation"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService" />
</intent-filter>
</service>
Once you have the call object, answering it's as simple as call.answer(). I suggest that when you get the stuff above working, run a couple of test calls to get to know when the different callbacks are invoked.
Regarding tutorials, I couldn't find any when I was looking into this, but that was over a year ago...
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With