Замена в приложении вызова

Фон

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

При поиске в сети я обнаружил пакет android.telecom.incallservice (доступен в API 23). Этот сервис реализуется любым приложением, которое хочет предоставить пользовательский интерфейс для управления телефонными звонками.

Это кажется многообещающим, но у меня проблемы с тем, чтобы заставить его работать. Я создал простой сервис, расширяющий InCallService, и объявил его в своем манифесте, как описано в документации. Тем не менее, я ожидал, что смогу изменить стандартное телефонное приложение в настройках на свое собственное, но я могу найти только стандартное телефонное приложение.

Код

Это декларация манифеста из документов. Я заменил BIND_IN_CALL_SERVICE на BIND_INCALL_SERVICE так как полагаю, что это опечатка.

<service android:name="your.package.YourInCallServiceImplementation" 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>

Вопросы

  1. Возможно ли даже стороннему приложению заменить приложение по умолчанию в приложении вызовов?

  2. Есть ли примеры реализаций, использующие этот API, которые я могу использовать в качестве ссылки? Я нашел реализацию Google, но это системное приложение, которое использует некоторые разрешения, которые недоступны для других приложений (например: android.permission.MODIFY_PHONE_STATE).

  3. Правильно ли я полагаю, что после предоставления правильной регистрации манифеста InCallService и реализации заглушки я мог ожидать найти мое приложение в разделе " Default Apps → Phone? Нужно ли декларировать что-то еще?

Благодарю.

Ответ 1

В соответствии с документами и когда вы сами комментируете, вам нужно добавить это в свой манифест:

<service android:name="your.package.YourInCallServiceImplementation"
          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>

android:name должно быть заменено классом, который реализует этот сервис.


 <activity android:name="your.package.YourDialerActivity">
      <intent-filter>
           <action android:name="android.intent.action.DIAL" />
           <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
 </activity>

android:name должно быть заменено классом, который реализует основное действие для вашей собственной реализации номеронабирателя.

Здесь вы можете найти больше информации об этом: https://developer.android.com/guide/topics/connectivity/telecom/selfManaged

А вот пример проекта, который вы можете использовать в качестве руководства: https://github.com/arekolek/simple-phone

И это: fooobar.com/questions/2399260/...

Ответ 2

  1. Возможно ли даже стороннему приложению заменить приложение по умолчанию в приложении вызовов?

Да, начиная с API 23 это возможно.

  1. Есть ли примеры реализаций, использующие этот API, которые я могу использовать в качестве ссылки? Я нашел реализацию Google, но это системное приложение, которое использует некоторые разрешения, которые недоступны для других приложений (например: android.permission.MODIFY_PHONE_STATE).

Единственный известный мне пример - созданный мной пример https://github.com/arekolek/simple-phone, который также был упомянут в другом ответе.

  1. Правильно ли я полагаю, что после предоставления правильной регистрации манифеста InCallService и реализации заглушки я мог ожидать найти мое приложение в разделе " Default Apps → Phone? Нужно ли декларировать что-то еще?

Вообще-то, нет.

Как упомянуто в другом ответе на эту тему, вам вообще не нужен InCallService чтобы появиться в этом списке.

Тем не менее, вам нужно зарегистрировать операцию с двумя фильтрами намерений, один со схемой tel uri, а другой - с пустой схемой (одного из них недостаточно):

<intent-filter>
    <action android:name="android.intent.action.DIAL" />
    <data android:scheme="tel" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.DIAL" />
</intent-filter>

Это смутно упоминается в документах и явно указано в коде AOSP.

Этого достаточно, чтобы появиться в этом списке. Только тогда, чтобы предоставить пользовательский интерфейс для вызова, вам действительно понадобится InCallService.