Answer incoming call using android.telecom and InCallService

I would recommend you to see this project to build a dialer app for Android. https://github.com/HiddenPirates/Dialer


How do you get notified about, and acquire instances of GSM Calls

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).

How does one answer these calls

If the user wants to answer the call, you need to invoke the method Call#answer(int) with VideoProfile.STATE_AUDIO_ONLY for example.

What is the life-cycle of the callbacks on this class

Check out Call.Callback for events that can happen with a single call.

Does Google provide any actual tutorial for this that I haven't found

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!


I guess Google must've read this question, because apparently on Android 8, a new permission finally allows answering calls through a 3rd party dev-facing permission.

android.permission.ANSWER_PHONE_CALLS (...) allows apps to answer incoming phone calls programmatically

No details yet though, since the documentation for API 26 hasn't been released yet. I'll make sure to update this answer when they do.

EDIT: user arekolek provided an answer that works perfectly on the original API version of this question (at the time of asking, API was 23, even though the question mentions API 21), thus he gets the tick for right answer. Refer to his answer if you want to implement an incall screen that targets minimum SDK of 23. Note you might need API-dependant code or compat library tweaks if you want it to work on more recent APIs that deprecate (or restrict) usage of the provided sample code. the github repo works as I initially intended.