6

Android API level 23 added InCallService to provide the user-interface for managing phone calls. The documentation provides an example manifest registration but I couldn't get it to work. The app compiles fine but Default Apps in settings doesn't show my app.

The only place I found any information about the subject was a StackOverflow question that was closed a year ago. Comment on that question proposed to add android.intent.action.DIAL activity but that didn't help me either. I have tried various combinations of other intent's too (android.intent.action.CALL_DIAL and android.intent.action.ANSWER) in my activity.

Are there any working examples of code needed to replace the phone app? Do the classes need to provide some working methods for the app to show?

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
hannujaakkola
  • 63
  • 1
  • 2
  • 7
  • 1
    I have an application with 'InCallService' , it is working fin e in android 6. But, I run on Android 7 it is not getting the InCallService call backs. Do you have any idea ? . I have posted a question few days ago regarding this, https://stackoverflow.com/questions/45079210/incallservice-not-working-in-android-nougat , didn't get any reply. – Vineesh TP Jul 17 '17 at 04:11
  • @VineeshTP How did you manage to make it work on Android 6? Please share the solution if you can – Piotr Aleksander Chmielowski Feb 02 '18 at 21:42
  • @PiotrAleksanderChmielowski: https://developer.android.com/reference/android/telecom/InCallService.html, Use the Android documentation code it self. Which is mentioned in the first paragraph itself. – Vineesh TP Feb 03 '18 at 05:57

1 Answers1

9

The app compiles fine but Default Apps in settings doesn't show my app.

To have your app listed as a Phone app, you must have an activity with at least those intent filters (to handle both cases mentioned in documentation of ACTION_DIAL, also mentioned in DefaultDialerManager hidden class):

<intent-filter>
    <action android:name="android.intent.action.DIAL" />
    <data android:scheme="tel" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.DIAL" />
</intent-filter>

And to be honest, that's a bit counterintuitive, because setting the default Phone app is separate from setting a default Dialer – the former controls only the ongoing call UI, while the latter controls only the dialing UI.

The above minimum can be improved a bit, to allow setting your dialer as a default, and launching from web browser, by using these intent filters instead:

<intent-filter>
    <!-- Handle links from other applications -->
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.DIAL" />
    <!-- Populate the system chooser -->
    <category android:name="android.intent.category.DEFAULT" />
    <!-- Handle links in browsers -->
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="tel" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.DIAL" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

The Dialer app in AOSP has even more filters declared.

You can make it easier for the user to set your app as the default Phone app with the help from TelecomManager:

if (getSystemService(TelecomManager::class.java).defaultDialerPackage != packageName) {
    Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER)
            .putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, packageName)
            .let(::startActivity)
}

This will show a dialog similar to this:

change default dialer dialog

Refer to Answer incoming call using android.telecom and InCallService for what you need to do to actually handle the calls themselves.

Here's the code for an app that implements the minimum needed to handle dialing, and accepting/rejecting/ending calls in its own UI:

https://github.com/arekolek/simple-phone

arekolek
  • 9,128
  • 3
  • 58
  • 79
  • Can you tell please how i can reject incoming call using this method? it vibrates a little bit before rejecting by using call.reject() method but i don't want that behavior. – Mateen Chaudhry Sep 02 '18 at 03:09
  • @MateenChaudhry I encourage you to post that as a separate question – arekolek Sep 02 '18 at 19:25
  • Here is the question. if you can answer please answer. https://stackoverflow.com/questions/52130348/reject-call-silently-using-incallservice/52130709?noredirect=1#comment91219240_52130709 – Mateen Chaudhry Sep 03 '18 at 02:18
  • 1
    its not working in MIUI xiomi device. I think its work only Native Android OS not custom ROM. – Pinak Gauswami Dec 21 '18 at 11:57
  • That's how I managed to set my app as default phone app: `if (getSystemService(TelecomManager.class).getDefaultDialerPackage() != getPackageName()) { Intent ChangeDialer = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER); ChangeDialer.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName()); startActivity(ChangeDialer); }` – Aliton Oliveira Apr 05 '19 at 01:26
  • @arekolek, the app you recommended works perfectly. But I am facing difficulties to pass object to **CallActivity**. I appreciate if you could help me. https://stackoverflow.com/q/55620683/4300670 – Aliton Oliveira Apr 10 '19 at 20:43
  • is there a java version of this project? – user13267 Jun 10 '19 at 09:23
  • 1
    @user13267 I was made aware of [one such Java fork](https://github.com/Abror96/CustomPhoneDialer), I can see it could be improved, but I've been told that it works – arekolek Jun 10 '19 at 10:46
  • Were you able to achieve enabling outspeaker i tried but its not working through setAudioRoute(int route) anyhelp is appreciated? – kondal Sep 28 '20 at 14:16
  • TelecomManager.ACTION_CHANGE_DEFAULT_DIALER is no longer supported since Q, please use android.app.role.RoleManager.createRequestRoleIntent(String) with android.app.role.RoleManager.ROLE_DIALER instead Could you, please, update your simple-phone app. – Juha Apr 28 '23 at 07:27