Aaron
Aaron

Reputation: 75

Android Telecom System RoleManager

I am trying to implement a calling application. For APIs < 29 I can select my dialer application as the default dialer. But for API >= 29, I cannot get the prompt to show and I cannot set my application to the default dialer under the settings. It doesn't show up as an option. It does with API < 29 though. Here is my manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ceptor">

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

    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Ceptor">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.CALL" />
                <action android:name="android.intent.action.CALL_BUTTON" />
                <action android:name="android.intent.action.ANSWER" />
                <action android:name="android.intent.category.DEFAULT" />
                <action android:name="android.intent.category.BROWSABLE" />
                <action android:name="android.intent.action.VIEW" />
                <!-- The directives below this comment seem to be sufficient for API < 29 -->
                <action android:name="android.intent.action.DIAL" />
                <data android:scheme="tel" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.DIAL" />
                <!-- The directives above this comment seem to be sufficient for API < 29 -->
                <action android:name="android.intent.category.DEFAULT" />
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.CALL" />
                <action android:name="android.intent.action.CALL_BUTTON" />
                <action android:name="android.intent.action.ANSWER" />
            </intent-filter>

        </activity>

        <receiver android:name=".CeptorBootCompleteReceiver" android:directBootAware="true" >
            <intent-filter>
                <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
                <action android:name="android.intent.action.QUICKBOOT_POWERON" />
            </intent-filter>
        </receiver>

        <service android:name=".CeptorConnectionService"
            android:label="The_label_for_my_connection_service"
            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
            <intent-filter>
                <action android:name="android.telecom.ConnectionService" />

            </intent-filter>
        </service>


    </application>

</manifest>

For API < 29 it looks like DIAL and DEFAULT are all that is needed.

Here is where I am doing my work to register my stuff with the TelecomManager.

        // change from com.google.android.dialer

        if (Build.VERSION.SDK_INT >= 29)
        {
            RoleManager rm = (RoleManager) getSystemService(Context.ROLE_SERVICE);
            Intent intent = rm.createRequestRoleIntent(RoleManager.ROLE_DIALER);
            startActivityForResult(intent, 1);
        }
        else
        {
            Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
            intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME, this.getPackageName());
            startActivity(intent);
        }


        TelecomManager tm = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);

        // Create a new PhoneAccountHandle with the name "CeptorHandle" which uses my CeptorConnectionService.
        ComponentName cn = new ComponentName("com.example.ceptor", "com.example.ceptor.CeptorConnectionService");
        PhoneAccountHandle pah = new PhoneAccountHandle(cn,"CeptorHandle");

        
        // Create a new phone account which is associated with the PhoneAccountHandle "CeptorHandle".
        final int capabilities =    PhoneAccount.CAPABILITY_CALL_PROVIDER |
                                    PhoneAccount.CAPABILITY_CONNECTION_MANAGER;

        PhoneAccount pa = PhoneAccount.builder(pah, "CeptorHandle").setCapabilities(capabilities).build();

    }

So we see here that I'm using ROLE_SERVICE and ROLE_DIALER for my RoleManager. However, I don't ever get a prompt. From reading about it here:

https://proandroiddev.com/android-q-to-the-res-q-9a88733aedda

I see that it says:

For the RoleManager to resolve a request properly, your Manifest must specify categories, permissions, or additional intent filters for the role to properly be held. The request will be automatically canceled if you fail to do so

But Even on the official Android documentation I don't see an exact list of specific categories, permissions, or additional intent filters for the role ROLE_DIALER.

https://developer.android.com/reference/androidx/core/role/RoleManagerCompat#ROLE_DIALER

I'm thinking the difference between APIs is that older APIs use an Intent with the TelecomManager but newer APIs use this new RoleManager. I think that's it but maybe I'm way off.

So in conclusion... WHY DOES THIS WORK FOR API < 29 BUT NOT OTHERWISE?

Upvotes: 1

Views: 886

Answers (1)

Aaron
Aaron

Reputation: 75

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

Should have been

<category android:name="android.intent.category.DEFAULT" />

Upvotes: 1

Related Questions