Android Q has introduced CallRedirectionService
API - seems like one of the way 3rd party apps can use it is to cancel calls and reroute them over VoIP - essentiall
Got it working (looking here). The next code will block all outgoing calls (it's just a sample...) :
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (!isRedirection())
roleAcquire(RoleManager.ROLE_CALL_REDIRECTION)
}
private fun isRedirection(): Boolean {
return isRoleHeldByApp(RoleManager.ROLE_CALL_REDIRECTION)
}
private fun isRoleHeldByApp(roleName: String): Boolean {
val roleManager: RoleManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
roleManager = getSystemService(RoleManager::class.java)
return roleManager.isRoleHeld(roleName)
}
return false
}
private fun roleAcquire(roleName: String) {
val roleManager: RoleManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (roleAvailable(roleName)) {
roleManager = getSystemService(RoleManager::class.java)
val intent = roleManager.createRequestRoleIntent(roleName)
startActivityForResult(intent, ROLE_ACQUIRE_REQUEST_CODE)
} else {
Toast.makeText(this, "Redirection call with role in not available", Toast.LENGTH_SHORT).show()
}
}
}
private fun roleAvailable(roleName: String): Boolean {
val roleManager: RoleManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
roleManager = getSystemService(RoleManager::class.java)
return roleManager.isRoleAvailable(roleName)
}
return false
}
companion object {
private const val ROLE_ACQUIRE_REQUEST_CODE = 4378
}
}
MyCallRedirectionService.kt
class MyCallRedirectionService : CallRedirectionService() {
override fun onPlaceCall(handle: Uri, initialPhoneAccount: PhoneAccountHandle, allowInteractiveResponse: Boolean) {
Log.d("AppLog", "handle:$handle , initialPhoneAccount:$initialPhoneAccount , allowInteractiveResponse:$allowInteractiveResponse")
cancelCall()
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.callredirectionservicesample">
<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/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyCallRedirectionService"
android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">
<intent-filter>
<action android:name="android.telecom.CallRedirectionService" />
</intent-filter>
</service>
</application>
</manifest>
The problem is that at the moment documentation is not full and sample in documentation is not correct. To fix this, in your AndroidManifest it is needed to change
android:permission="android.permission.BIND_REDIRECTION_SERVICE"
to
android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE"
This permission is incorrectly written inside the google documentation for https://developer.android.com/reference/android/telecom/CallRedirectionService.html currently.
Also, it is required to ask user to allow your application play this role. In google documentation this part missing at the moment :
RoleManager roleManager = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
roleManager = (RoleManager) getSystemService(Context.ROLE_SERVICE);
Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_REDIRECTION);
startActivityForResult(intent, 1);}