为呼出电话实现ConnectionService

12
我正在尝试实现ConnectionService、PhoneAccount和PhoneAccountHandle以获取我的外拨电话的断开原因(例如:用户拒绝接听、无法连接等)。到目前为止,我已经能够使用customPhoneAccount发起电话呼叫,但该电话呼叫从未连接,因此我无法获取响应。 以下是我目前编写的代码:
register()是从我的Activity调用以注册电话账户的方法:
public void register() {
    TelecomManager manager = (TelecomManager) getSystemService(TELECOM_SERVICE);
    PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(
            new ComponentName(getPackageName(),
                    MyConnectionService.class.getName()), "myConnectionServiceId");
    PhoneAccount.Builder builder = PhoneAccount.builder(phoneAccountHandle, "CustomAccount");
    builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | PhoneAccount.CAPABILITY_CONNECTION_MANAGER);
    PhoneAccount phoneAccount = builder.build();
    manager.registerPhoneAccount(phoneAccount);
}

call()方法用于发起调用:

 public void call() {
    TelecomManager manager = (TelecomManager) getSystemService(TELECOM_SERVICE);
    PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(
            new ComponentName(getPackageName(),
                    MyConnectionService.class.getName()), "myConnectionServiceId");
    Bundle test = new Bundle();
    test.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle);
    manager.placeCall(Uri.parse("tel:" + "1212312312"), test);
}

这是我的连接服务:

public class MyConnectionService extends ConnectionService {

public static final String TAG = MyConnectionService.class.getName();
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
    Log.d(TAG, "On Start");
    return super.onStartCommand(intent, flags, startId);
}

@Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
    Connection connection = super.onCreateOutgoingConnection(connectionManagerPhoneAccount, request);
    Log.d(TAG, connection.getDisconnectCause().getReason());
    return connection;
}

@Override
public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
    if (request != null) {
        Log.d(TAG, request.toString());
    }
    super.onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount, request);
}

我已经尝试了不同的功能以及所有在其他与ConnectionService相关的线程中提到的选项,但是我无法得到期望的结果,有人能帮助我吗?


1
你能够实现它吗?我只能使用ConnectionService进行虚拟/模拟呼叫,但我需要能够进行实际呼叫。查看了Android源代码,似乎有很多事情需要做。我知道应该有更好的方法。 - artsylar
@artsylar:不,我没能让它工作,而且我也不确定在过去的两年里是否有所改变,但当时很明显Android不允许“获取我的呼出电话断开原因”。 - Saurabh7474
@Saurabh7474,我卡在实现connectionService API上了。你能否提供一些集成connectionService的示例? - Shashank Gupta
也许是因为 super.onCreateOutgoingConnection 返回了 null 呢? - Displee
1个回答

5
一些事情:
  1. 您不应该使用 PhoneAccount.CAPABILITY_CONNECTION_MANAGER,因为它有一个特殊的用途,不适用于您的用例,并且需要特殊权限。

  2. 您的 onCreateOutgoingConnection 方法不应该调用超级版本;那个方法是在基本的 ConnectionService 类中的一个空白方法。电信调用您重写的 onCreateOutgoingConnection,以便您可以提供 Connection 的新实例。

请查看 Android 开源的 TestConnectionService 类;它实现了一个简单的 ConnectionService: https://android.googlesource.com/platform/packages/services/Telecomm/+/master/testapps/src/com/android/server/telecom/testapps/TestConnectionService.java

1
TestConnectionService不是用于仅进行虚拟/模拟呼叫的吗?我也想使用ConnectionService实现我们自己的通话应用程序。我希望我的应用程序能够进行真正的运营商呼叫。使用ConnectionService类是否可能实现这一点? - artsylar
1
我建议你可以参考TestConnectionService的实现方式作为使用API的例子。 ConnectionService API不允许你的应用去进行真实的载波呼叫,它的主要目的是将VoIP呼叫解决方案的功能包装起来,以便这些呼叫会出现在设备的拨号器/电话应用程序中。 如果你想要拨打电话,你需要获得android.permission.CALL_PHONE权限,并使用TelecomManager#placeCall来进行呼出。 - TGunn
@TGunn,您能否提供一些实现连接服务的示例? - Shashank Gupta
示例代码非常有帮助,谢谢 @TGunn。 - Amos
@TGunn,如果普通电话和VoIP电话之间发生冲突,我们如何断开其他电话? Connection类中的覆盖方法没有被触发,你能帮忙吗? - tronku
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接