Android Q引入了CallRedirectionService
API-似乎第三方应用程序可以使用它的一种方式是取消呼叫并通过VoIP重新路由-本质上是拦截电话。
我正在尝试如下实现此类
public class CallMonitorService extends CallRedirectionService {
private static final String TAG = "CallMonitorService";
public CallMonitorService() {
}
@Override
public void onPlaceCall(Uri uri, PhoneAccountHandle phoneAccountHandle, boolean b) {
Log.e(TAG, "onPlaceCall:### ");
}
}
如您所见,我正在覆盖onPlaceCall
中的抽象方法CallRedirectionService
,并仅保留一条日志语句来检查/测试此回调方法挂钩是否由Android框架调用。
我在Manifest.xml中以及以下内容中添加了此服务,这是CallRedirectionService
类的源代码中记录的内容
<service
android:name=".CallMonitorService"
android:permission="android.permission.BIND_REDIRECTION_SERVICE"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.telecom.CallRedirectionService"/>
</intent-filter>
</service>
我的猜测是,当Android系统发出去电时,此onPlaceCall
将被调用,然后我们可以编写我们的自定义代码以对去电进行进一步的操作。尚不确定100%是否应该CallRedirectionService
才能工作-到目前为止,在developer.android.com中尚无用于实现CallRedirectionService
的示例。我在minSdkVersion 29
中设置了targetSdkVersion 29
build.gradle
无论何时拨打电话-服务中的onPlaceCall
都不会被调用。
我正在使用Android Q Emulator进行测试,因为我没有运行Android Q的Android手机来对此进行测试-无法通过拨打模拟电话在Android Emulator上进行测试,或者我还缺少什么?
答案 0 :(得分:6)
问题在于,当前文档不完整,文档中的样本不正确。 要解决此问题,需要在AndroidManifest中进行更改
android:permission="android.permission.BIND_REDIRECTION_SERVICE"
到
android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE"
此权限当前错误地写入了https://developer.android.com/reference/android/telecom/CallRedirectionService.html的google文档中。
此外,还要求用户允许您的应用程序扮演此角色。在Google文档中,此部分目前不存在:
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);}
答案 1 :(得分:0)
使其正常运行(看起来https://github.com/mobxjs/mobx-react/issues/868)。下一个代码将阻止所有拨出电话(这只是一个示例...):
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>