Пользовательское приложение для набора номера Android, соединения не активированы - PullRequest
1 голос
/ 30 апреля 2019

Я пытаюсь реализовать базовое приложение для набора номера, которое также должно обрабатывать входящие вызовы. Сценарий состоит в том, что пользователь устанавливает приложение в качестве номеронабирателя по умолчанию, и с этого момента каждый входящий и исходящий вызов должен поступать в реализацию ConnectionService приложения.

Я не хочу переопределять встроенный интерфейс вызова, мне просто нужно добавить дополнительную логику к обратным вызовам соединения. Например, я хочу отправить намерение вещания, когда ответ на соединение и т. Д.

Исходя из этой документации, я решил, что должен реализовать управляемый системой 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 с возможностями PhoneAccount.CAPABILITY_CONNECTION_MANAGER, созданные вызовы не становятся - из-за отсутствия лучшего слова - активными, но обратные вызовы Соединения правильно вызываются. Поэтому я могу инициировать исходящий звонок, но другой телефон никогда не получит уведомление о входящем звонке. Или, если я начну вызов с другого телефона, устройство, на котором запущено мое приложение, перейдет к его методу 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" />

А вот регистрация активности и реализация 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>
...