Responda llamadas entrantes usando android.telecom e InCallService

Desde la API 21, Google ha agregado funciones a android.telecom en general, especialmente al implementar más miembros de TelecomManager y la incorporación de InCallService . Se supone que este último permite que las aplicaciones de terceros que no sean del sistema proporcionen y reemplacen la funcionalidad del sistema. Pantalla de llamada en la aplicación: la ventana que aparece y permite la acción en EXTRA_STATE_OFFHOOK o EXTRA_STATE_RINGING (es decir, entrantes y salientes) llamadas telefónicas).

Actualmente, solo esta pantalla tiene control total del timbre y las llamadas activas y las devoluciones de llamada del sistema asociadas con información detallada, mediante el permiso MODIFY_PHONE_STATE restringido por la raíz y una gran cantidad de código AOSP seguro al que ni siquiera se puede acceder por reflexión. Es notablemente uno de los códigos más cambiados en los sabores ROM de diferentes fabricantes, junto con el iniciador, los contactos y la cámara.

Esto es muy bonito, pero …

¿Cómo se desarrolla realmente un InCallService de terceros?

A saber:

  1. ¿Cómo se le notifica y adquiere instancias de llamadas GSM?
  2. ¿Cómo responde uno estas llamadas?
  3. ¿Cuál es el ciclo de vida de las devoluciones de llamada en esta clase?
  4. ¿Google proporciona algún tutorial real para esto que no he encontrado?

No voy a pedir respuestas para todos estos a la vez, pero cualquier respuesta probablemente se asocie con las otras preguntas. Esto es amplio pero intrínsecamente necesario: no hay ningún otro ejemplo en la web con el que haya tropezado, aparte del código AOSP, y ese código se basa en la suposición de privilegios de raíz, lo que lo hace inutilizable para el desarrollo de aplicaciones de terceros. propósitos.

¿Cómo se le notifica y adquiere instancias de llamadas GSM?

En primer lugar, el usuario deberá seleccionar su aplicación como la aplicación de teléfono predeterminada. Consulte Cómo reemplazar la aplicación de teléfono predeterminada en Android 6 y 7 con InCallService para obtener una forma de hacerlo.

También necesita definir una implementación de InCallService el sistema se vinculará y le notificará sobre la llamada:

       

Allí debe manejar al menos onCallAdded (configurar oyentes en Call , iniciar su UI – actividad – para la llamada) y onCallRemoved (eliminar oyentes).

¿Cómo responde uno estas llamadas?

Si el usuario desea contestar la llamada, necesita invocar el método Call#answer(int) con VideoProfile.STATE_AUDIO_ONLY por ejemplo.

¿Cuál es el ciclo de vida de las devoluciones de llamada en esta clase?

Consulte Call.Callback para ver eventos que pueden suceder con una sola llamada.

¿Google proporciona algún tutorial real para esto que no he encontrado?

No sé acerca de Google, pero puedes ver mi ejemplo simplificado https://github.com/arekolek/simple-phone

Siga los consejos del segundo comentario de Reemplazar en la aplicación de llamadas . Además, necesita un servicio que implemente la interfaz InCallService. Cuando llega una llamada, se llamará al método onCallAdded (llamada de llamada), que le proporciona una referencia al objeto de llamada.

       

Una vez que tenga el objeto call, responder es tan simple como call.answer (). Sugiero que cuando obtenga el funcionamiento anterior, ejecute un par de llamadas de prueba para saber cuándo se invocan las diferentes devoluciones de llamada.

En cuanto a los tutoriales, no pude encontrar ninguno cuando estaba investigando esto, pero eso fue hace más de un año …

¡Espero que esto ayude!

Supongo que Google debe haber leído esta pregunta, porque aparentemente en Android 8, un nuevo permiso finalmente permite contestar llamadas a través de un permiso de desarrolladores externos .

android.permission ANSWER_PHONE_CALLS (…) permite a las aplicaciones responder llamadas telefónicas entrantes mediante progtwigción

Sin embargo, aún no hay detalles, ya que la documentación para API 26 aún no se ha publicado. Me aseguraré de actualizar esta respuesta cuando lo hagan.

EDITAR: el usuario arekolek proporcionó una respuesta que funciona perfectamente en la versión original de la API de esta pregunta (en el momento de formular la pregunta, API tenía 23 años, a pesar de que la pregunta menciona API 21), por lo que recibe la respuesta correcta. Consulte su respuesta si desea implementar una pantalla de invocación que se dirija a un SDK mínimo de 23. Tenga en cuenta que es posible que necesite un código dependiente de API o ajustes de biblioteca compatible si desea que funcione en API más recientes que deprecian (o restringen) el uso del proporcionado código de muestra. el repository de github funciona como inicialmente pretendí.