Ответ на входящий вызов с использованием android.telecom и InCallService

Начиная с API 21, Google добавляет функции android.telecom в целом, особенно путем внедрения большего числа членов TelecomManager и добавление InCallService. Этот последний, как предполагается, позволяет несистемным, сторонним приложениям предоставлять и заменять функциональные возможности экрана вызова вызовов Calls при вызове - окно, которое всплывает, и разрешает действие в передачах EXTRA_STATE_OFFHOOK или EXTRA_STATE_RINGING (например, т.е. входящие и исходящие телефонные звонки).

В настоящее время только этот экран имеет полный контроль над вызовами и активными вызовами и связанными с ними системными обратными вызовами с мелкозернистой информацией с помощью ограниченного корнем разрешения MODIFY_PHONE_STATE и большого количества защищенного кода AOSP, даже недоступного для отражения. Это, в частности, один из самых измененных фрагментов кода в разных версиях ROM производителей, вместе с пусковой установкой, контактами и камерой.

Это все очень красиво, но...

Как вы на самом деле разрабатываете сторонний InCallService?

А именно:

  • Как вы получаете уведомление и получаете экземпляры GSM-звонков
  • Как отвечать на эти вызовы
  • Каков жизненный цикл обратных вызовов в этом классе
  • Предоставляет ли Google какой-либо фактический учебник для этого, который я не нашел.

Я не буду задавать ответы на все эти вопросы сразу, но любой ответ, вероятно, ассоциируется с другими вопросами. Это широко, но по своей сути это должно быть: в Интернете нет примера, который я наткнулся на AOSP-код, и этот код основан на предположении о привилегиях root, что делает его непригодным для разработки сторонних приложений целей.

Ответ 1

Как вы получаете уведомления и приобретаете экземпляры звонков GSM

Во-первых, пользователю необходимо выбрать ваше приложение в качестве приложения телефона по умолчанию. Обратитесь к разделу Замена телефонного приложения по умолчанию на Android 6 и 7 на InCallService, чтобы узнать, как это сделать.

Вам также необходимо определить реализацию InCallService к которой будет привязана система, и уведомить вас о вызове:

<service
    android:name=".CallService"
    android:permission="android.permission.BIND_INCALL_SERVICE">
    <meta-data
        android:name="android.telecom.IN_CALL_SERVICE_UI"
        android:value="true" />
    <intent-filter>
        <action android:name="android.telecom.InCallService" />
    </intent-filter>
</service>

Там вы должны обработать как минимум onCallAdded (настроить прослушиватели на Call, запустить свой UI - активность - для вызова) и onCallRemoved (удалить прослушивателей).

Как ответить на эти звонки

Если пользователь хочет ответить на вызов, вам нужно вызвать метод Call#answer(int) с VideoProfile.STATE_AUDIO_ONLY.

Каков жизненный цикл обратных вызовов в этом классе

Проверьте Call.Callback для событий, которые могут произойти с одним вызовом.

Предоставляет ли Google какой-либо реальный учебник для этого, который я не нашел

Я не знаю о Google, но вы можете проверить мой упрощенный пример https://github.com/arekolek/simple-phone

Ответ 2

Следуйте рекомендациям второго комментария Замена в приложении для звонков. Кроме того, вам нужна служба, которая реализует интерфейс InCallService. Когда поступит вызов, будет вызываться метод onCallAdded (Call call), который даст вам ссылку на объект вызова.

<service
  android:name=".InCallServiceImplementation"
  android:enabled="true"
  android:exported="true"
  android:permission="android.permission.BIND_INCALL_SERVICE">

  <meta-data
    android:name="android.telecom.IN_CALL_SERVICE_UI"
    android:value="true" />

  <intent-filter>
    <action android:name="android.telecom.InCallService" />
  </intent-filter>
</service>

Как только у вас есть объект вызова, он отвечает так же просто, как call.answer(). Я предлагаю, чтобы, когда вы загружаете материал выше, запустите несколько тестовых вызовов, чтобы узнать, когда вызываются разные обратные вызовы.

Что касается учебников, я не мог найти их, когда смотрел на это, но это было более года назад...

Надеюсь, это поможет!

Ответ 3

Думаю, Google должен был прочитать этот вопрос, потому что, по-видимому, на Android 8 новое разрешение наконец позволяет отвечать на вызовы через стороннее разрешение, обращенное к экрану.

android.permission. ANSWER_PHONE_CALLS (...) позволяет приложениям отвечать входящие телефонные звонки программно

Пока нет деталей, поскольку документация по API 26 еще не выпущена. Я обязательно обновлю этот ответ, когда они это сделают.

EDIT: пользователь iskolek предоставил ответ, который отлично работает на исходной версии API этого вопроса (во время запроса API был 23, хотя вопрос упоминает API 21), поэтому он получает галочку за правильный ответ. Обратитесь к его ответу, если вы хотите реализовать экран incall, который рассчитан на минимальный SDK на 23. Обратите внимание, что вам может понадобиться API-зависимый код или настройки библиотеки совместимости, если вы хотите, чтобы он работал с более новыми API-интерфейсами, которые осуждают (или ограничивают) использование предоставил образец кода. репозиторий github работает так, как я изначально планировал.