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

时间:2019-04-30 10:46:25

标签: android android-dialer android-phone-call

我正在尝试实现一个基本的拨号器应用程序,该应用程序还应该处理来电。这种情况是用户将应用程序设置为默认拨号程序,然后,每个传入和传出的呼叫都应到达应用程序的ConnectionService实现中。

我不想覆盖内置的调用UI,我只需要向Connection回调添加一些额外的逻辑即可。例如,我想发送广播意向,当回答了Conention时,等等。

基于this文档,我认为我应该实现一个系统管理的ConnectionService。

我已经通过以下方式实现了ConnectionService,并且效果很好,在有呼入或呼出电话的情况下会调用回调:

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,则由于缺少更好的单词,创建的呼叫不会变为活动状态,但是可以正确调用Connection的回调。因此,我可以发起拨出电话,但是另一部电话永远不会收到来电通知。 或者,如果我从另一部电话发起呼叫,则运行我的应用程序的设备将进入其onCreateIncomingConnection()方法,并且可以接听该呼叫,但发起方的电话仍在拨号。

我已经按照以下方式注册了PhoneAccount,但我怀疑问题出在这里:

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>

1 个答案:

答案 0 :(得分:0)

await Task.WhenAny(method1,method1); // wait for something to finish
await method2(); // await for method 2
await Task.WhenAll(method1,method1); // run it all again

// or endlessly
while(!theEndofTheUniverse)
{
   await Task.WhenAny(method1,method1);
   await method2();
} // rinse and repeate