安卓自定义拨号器应用程序,连接未激活



我正在尝试实现一个基本的拨号器应用程序,该应用程序也应该处理来电。该方案是用户将应用设置为默认拨号器,从那时起,每个传入和传出呼叫都应到达应用的 ConnectionService 实现中。

我不想覆盖内置调用 UI,我只需要向连接回调添加一些额外的逻辑。例如,我想发送广播意图,何时应答Conenction等。

基于此文档,我认为我应该实现一个系统管理的连接服务。

我通过以下方式实现了连接服务,并且效果很好,在传入或传出呼叫的情况下调用回调:

public class DialerConnectionService extends ConnectionService {
NotificationManagerUtil notificationManager;
public DialerConnectionService() {
notificationManager = NotificationManagerUtil.getInstance();
}
@Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
return createConnection(request, false);
}
@Override
public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
notificationManager.createToast(getApplicationContext(), getString(R.string.error_place_outgoing_call));
}
@Override
public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
return createConnection(request, true);
}
@Override
public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
notificationManager.createToast(getApplicationContext(), getString(R.string.error_create_incoming_call));
}
private TelecomConnection createConnection(ConnectionRequest request, boolean isIncoming) {
TelecomConnection connection = new TelecomConnection(getApplicationContext(), isIncoming);
connection.setConnectionProperties(Connection.PROPERTY_SELF_MANAGED);
connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
String normalizedPhoneNumber = ContactsUtil.getInstance().normalizePhoneNumberFromUri(request.getAddress());
connection.setNormalizedPhoneNumber(normalizedPhoneNumber);
connection.setCallerDisplayName(ContactsUtil.getInstance().getContactName(getApplicationContext(), normalizedPhoneNumber), TelecomManager.PRESENTATION_ALLOWED);
connection.setExtras(request.getExtras());
if (isIncoming) {
connection.setRinging();
} else {
connection.setDialing();
}
connection.setInitializing();
CallManager.getInstance().addConnection(connection);
return connection;
}

}

问题是,如果我注册了一个具有PhoneAccount.CAPABILITY_CONNECTION_MANAGER功能的 PhoneAccount,创建的调用不会变为 - 由于缺乏更好的词 - 处于活动状态,但连接的回调被正确调用。因此,我可以发起拨出电话,但另一部电话永远不会收到来电通知。 或者,如果我从另一部手机发起呼叫,运行我的应用的设备将单步进入其 onCreateIncomingConnection() 方法,我将能够应答该呼叫,但发起电话仍将拨号。

我已经以以下方式注册了电话帐户,我怀疑问题出在这里的某个地方:

public boolean checkAccountHandler(Context ctx) {
PhoneAccountHandle phoneAccountHandle = getPhoneAccountHandle(ctx);
telecomManager = (TelecomManager) ctx.getSystemService(Context.TELECOM_SERVICE);
PhoneAccount phoneAccount = telecomManager.getPhoneAccount(phoneAccountHandle);
if (phoneAccount == null){
PhoneAccount account = PhoneAccount.builder(phoneAccountHandle, PHONE_ACCOUNT_LABEL)
.setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.build();
telecomManager.registerPhoneAccount(account);
return false;
}
return true;
}

这样,注册的帐户不会出现在Android的设置中,因此我无法让用户启用它。 有没有机会,这是问题的主要原因?

我的清单使用以下权限:

<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" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />

以下是 acctivity 和 ConnectionService 实现的注册:

<activity
android:name=".activity.MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tel" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service
android:name=".service.DialerConnectionService"
android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
<intent-filter>
<action android:name="android.telecom.ConnectionService" />
</intent-filter>
</service>
Bundle extras = new Bundle();
extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true);
extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, telecomManager.getUserSelectedOutgoingPhoneAccount());//This is the most important thing
telecomManager.placeCall(uri,extras);

最新更新