Why is the CallScreeningService not working after changing from Samsung Galaxy S9 to S23

173 views Asked by At

I recently switched from a Samsung Galaxy S9 to a Samsung Galaxy S23 and encountered an issue with the CallScreeningService in my Android app. The problem is that after granting my app the Call Screening Role on the new device and ringing the device with the app from another device, the call screening service is not functioning as expected.

I've included my AndroidManifest.xml and relevant code for the MainActivity and MyCustomCallScreeningService below for reference.

AndroidManifest.xml:

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

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.Android13CallScreening"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".services.MyCustomCallScreeningService"
            android:exported="true"
            android:permission="android.permission.BIND_SCREENING_SERVICE">
            <intent-filter>
                <action android:name="android.telecom.CallScreeningService" />
            </intent-filter>
        </service>

    </application>

</manifest>

MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        requestRole()
    }

    private val REQUEST_ID = 1

    fun requestRole() {
        val roleManager = getSystemService(Context.ROLE_SERVICE) as RoleManager
        val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING)
        startActivityForResult(intent, REQUEST_ID)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_ID) {
            if (resultCode == android.app.Activity.RESULT_OK) {
                println("Your app is now the call screening app")
            } else {
                println("Your app is not the call screening app")
            }
        }
    }

}

MyCustomCallScreeningService.kt

class MyCustomCallScreeningService: CallScreeningService() {
    override fun onScreenCall(callDetails: Call.Details) {
        System.out.println("Should print this message when there is an incoming call")
        respondToCall(callDetails, CallResponse.Builder().build())
    }
}

On my old Samsung Galaxy S9, the same app worked correctly and printed a message to the console when there was an incoming call. Additionally, I have tested the app on various emulators with different API levels, and it worked as expected. However, when I run it on my new Samsung Galaxy S23, there is no message printed to the console when there's an incoming call. I have also tested code that is not included here to block phone phone numbers using the CallScreeningService and it worked fine with the older device and the emulator, but not the Samsung Galaxy S23.

2

There are 2 answers

0
Peter Brna On BEST ANSWER

For people with a similar problem like mine with the call screening service not working or the print log not showing up, it's because the service is set to bind only for calls from numbers not saved in your contacts. I resolved this by making a call with a hidden number, which triggered the call screening service.

1
Ben Svendsen On

You need to ask for READ_CONTACTS permission to have call from contacts to be passed for screening:

Only calls where the handle scheme is PhoneAccount#SCHEME_TEL are passed for call screening. Further, only calls which are not in the user's contacts are passed for screening, unless the CallScreeningService has been granted Manifest.permission#READ_CONTACTS permission by the user. For outgoing calls, no post-dial digits are passed.

Calls with a Call.Details#getHandlePresentation() of TelecomManager#PRESENTATION_RESTRICTED, TelecomManager#PRESENTATION_UNKNOWN, TelecomManager#PRESENTATION_UNAVAILABLE or TelecomManager#PRESENTATION_PAYPHONE presentation are not provided to the CallScreeningService.