2

I'm currently having trouble getting my app to send the user a dialogue to set the default Dialler on API 29 but the same code is working fine below Android 10 (Q).

I test this No response from intent to prompt user to set default handler for SMS example as well but not working on mine. Then I followed https://developer.android.com/guide/topics/permissions/default-handlers but not solved my problem. Is there any special change for API level 29 or above to let the user set the default app?

Here's my working code (for below Android 10)

TelecomManager telecomManager = (TelecomManager) getSystemService(TELECOM_SERVICE);
        if (!getPackageName().equals(telecomManager.getDefaultDialerPackage())) {
            Intent intent = new Intent(ACTION_CHANGE_DEFAULT_DIALER)
                    .putExtra(EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, getPackageName());
            startActivity(intent);
        }

What I'm getting in logcat is here

enter image description here

Irfan Akram
  • 718
  • 1
  • 11
  • 20

2 Answers2

5

Yes, the API changed, see the note in the previous API here: https://developer.android.com/reference/android/telecom/TelecomManager#ACTION_CHANGE_DEFAULT_DIALER

And see here for the new API: https://developer.android.com/reference/android/app/role/RoleManager

basically, you need to do something like:

RoleManager roleManager = (RoleManager) getSystemService(Context.ROLE_SERVICE);
Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER);
startActivityForResult(Intent, CHANGE_DEFAULT_DIALER_CODE); // you need to define CHANGE_DEFAULT_DIALER as a static final int

and then you catch the response by implementing onActivityResult in your activity.

marmor
  • 27,641
  • 11
  • 107
  • 150
  • Thanks for the direction. I'm getting compile time error `Non-static method 'createRequestRoleIntent(java.lang.String)' cannot be referenced from a static context` at `createRequestRoleIntent`. Would to help me why am I getting this? – Irfan Akram Jun 28 '20 at 17:19
  • I solved it with the help of [this](https://stackoverflow.com/questions/56548666/callredirectionservice-implementation-not-working) but the direction was yours. Credit goes to you. Thank you so much. I have no words to thank you. I had got stuck for 14 days. – Irfan Akram Jun 28 '20 at 17:39
1

Here is the minimum that I needed to do in order make my app (baresip VoIP client) eligible as default Phone app:

In AndroidManifest.xml I added this permission:

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

In AndroidManifest.xml I added these two intent filters to MainActivity:

<intent-filter>
  <action android:name="android.intent.action.DIAL" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <action android:name="android.intent.action.DIAL" />
  <action android:name="android.intent.action.CALL" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="tel" />
  <data android:scheme="sip" />
</intent-filter>

In AndroidManifest.xml I added this new service:

<service
  android:name=".InCallService"
  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" />
  <meta-data
    android:name="android.telecom.IN_CALL_SERVICE_CAR_MODE_UI"
    android:value="false" />
  <intent-filter>
    <action android:name="android.telecom.InCallService" />
  </intent-filter>
</service>

I didn't check if the meta-data entries are really needed.

Then I implemented the InCallService service like this:

package <my package>

import android.app.Service
import android.content.Intent
import android.os.IBinder

// This is needed in order to allow choosing <my app> as default Phone app

class InCallService : Service() {

    override fun onBind(intent: Intent): IBinder {
        TODO("Return the communication channel to the service.")
    }
}

Finally, if there is need to request default dialer role from the app (and not only from Android Apps settings, it can be done like this (at API level 29+):

val dialerRoleRequest = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) {
    Log.d(TAG, "dialerRoleRequest succeeded: ${it.resultCode == Activity.RESULT_OK}")
}
        
if (roleManager.isRoleAvailable(RoleManager.ROLE_DIALER) && 
        !roleManager.isRoleHeld(RoleManager.ROLE_DIALER))
    dialerRoleRequest.launch(roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER))

Removing of default dialer role needs to be done from Android Apps settings.

Juha
  • 349
  • 2
  • 11