Core-Telecom

La bibliothèque Core-Telecom simplifie le processus d'intégration de votre application appelante à la plate-forme Android en fournissant un ensemble d'API robuste et cohérent.

Si vous souhaitez découvrir des implémentations pratiques, vous trouverez des exemples d'applications sur GitHub:

Configurer Core-Telecom

Ajoutez la dépendance androidx.core:core-telecom au fichier build.gradle de votre application:

dependencies {
    implementation ("androidx.core:core-telecom:1.0.0")
}

Déclarez l'autorisation MANAGE_OWN_CALLS dans votre fichier AndroidManifest.xml:

<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />

Enregistrer votre application

Enregistrez votre application appelante auprès d'Android à l'aide de CallsManager pour commencer à ajouter des appels au système. Lors de l'enregistrement, spécifiez les fonctionnalités de votre application (par exemple, la compatibilité audio et vidéo):

val callsManager = CallsManager(context)

val capabilities: @CallsManager.Companion.Capability Int =
    (CallsManager.CAPABILITY_BASELINE or
          CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)

callsManager.registerAppWithTelecom(capabilities)

Gestion des appels

Utilisez les API Core-Telecom pour créer et gérer le cycle de vie d'un appel.

Créer un appel

L'objet CallAttributesCompat définit les propriétés d'un appel unique, qui peut avoir les caractéristiques suivantes:

  • displayName: nom de l'appelant.
  • address: adresse de l'appel (par exemple, numéro de téléphone, lien de la réunion).
  • direction: entrante ou sortante.
  • callType: audio ou vidéo.
  • callCapabilities: compatible avec le transfert et la mise en attente.

Voici un exemple de création d'un appel entrant:

fun createIncomingCallAttributes(
    callerName: String,
    callerNumber: String,
    isVideoCall: Boolean): CallAttributesCompat {
    val addressUri = Uri.parse("YourAppScheme:$callerNumber")

    // Define capabilities supported by your call.
    val callCapabilities = CallAttributesCompat.CallCapability(
        supportsSetInactive = CallAttributesCompat.SUPPORTS_SET_INACTIVE // Call can be made inactive (implies hold)
    )

    return CallAttributesCompat(
        displayName = callerName,
        address = addressUri,
        direction = CallAttributesCompat.DIRECTION_INCOMING,
        callType = if (isVideoCall) CallAttributesCompat.CALL_TYPE_VIDEO_CALL else CallAttributesCompat.CALL_TYPE_AUDIO_CALL,
        callCapabilitiesCompat = callCapabilities
    )
}

Ajouter un appel

Utilisez callsManager.addCall avec CallAttributesCompat et les rappels pour ajouter un nouvel appel au système et gérer les mises à jour de surface à distance. callControlScope dans le bloc addCall permet principalement à votre application de passer à l'état de l'appel et de recevoir des mises à jour audio:

try {
    callsManager.addCall(
        INCOMING_CALL_ATTRIBUTES,
        onAnswerCall, // Watch needs to know if it can answer the call.
        onSetCallDisconnected,
        onSetCallActive,
        onSetCallInactive
    ) {
        // The call was successfully added once this scope runs.
        callControlScope = this
    }
}
catch(addCallException: Exception){
   // Handle the addCall failure.
}

Répondre à un appel

Répondre à un appel entrant dans CallControlScope:

when (val result = answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {
    is CallControlResult.Success -> { /* Call answered */ }
    is CallControlResult.Error -> { /* Handle error */ }
}

Refuser un appel

Refuser un appel à l'aide de disconnect() avec DisconnectCause.REJECTED dans CallControlScope:

disconnect(DisconnectCause(DisconnectCause.REJECTED))

Activer un appel sortant

Définissez un appel sortant comme actif une fois que la personne à l'autre bout de la ligne a répondu:

when (val result = setActive()) {
    is CallControlResult.Success -> { /* Call active */ }
    is CallControlResult.Error -> { /* Handle error */ }
}

Mettre un appel en attente

Utilisez setInactive() pour mettre un appel en attente:

when (val result = setInactive()) {
    is CallControlResult.Success -> { /* Call on hold */ }
    is CallControlResult.Error -> { /* Handle error */ }
}

Mettre fin à un appel

Déconnecter un appel à l'aide de disconnect() avec un DisconnectCause:

disconnect(DisconnectCause(DisconnectCause.LOCAL))

Gérer les points de terminaison audio des appels

Observer et gérer les points de terminaison audio à l'aide des Flow currentCallEndpoint, availableEndpoints et isMuted dans le CallControlScope

fun observeAudioStateChanges(callControlScope: CallControlScope) {
    with(callControlScope) {
        launch { currentCallEndpoint.collect { /* Update UI */ } }
        launch { availableEndpoints.collect { /* Update UI */ } }
        launch { isMuted.collect { /* Handle mute state */ } }
    }
}

Changez l'appareil audio actif à l'aide de requestEndpointChange():

coroutineScope.launch {
     callControlScope.requestEndpointChange(callEndpoint)
}

Compatibilité avec le premier plan

La bibliothèque utilise ConnectionService (Android 13, niveau d'API 33 ou version antérieure) ou foregroundtypes (Android 14, niveau d'API 34 ou version ultérieure) pour la compatibilité avec le premier plan.

Conformément aux exigences de premier plan, l'application doit publier une notification pour que les utilisateurs sachent qu'elle s'exécute au premier plan.

Pour vous assurer que votre application bénéficie de la priorité d'exécution au premier plan, créez une notification une fois que vous avez ajouté l'appel avec la plate-forme. La priorité de premier plan est supprimée lorsque votre application met fin à l'appel ou que votre notification n'est plus valide.

En savoir plus sur les services de premier plan

Assistance à distance pour Surface

Les appareils à distance (montres connectées, casques Bluetooth, Android Auto) peuvent gérer les appels sans interaction directe avec le téléphone. Votre application doit implémenter les lambdas de rappel (onAnswerCall, onSetCallDisconnected, onSetCallActive et onSetCallInactive) fournis à CallsManager.addCall pour gérer les actions lancées par ces appareils.

Lorsqu'une action à distance se produit, le lambda correspondant est appelé.

La réussite de l'exécution du lambda indique que la commande a été traitée. Si la commande ne peut pas être exécutée, le lambda doit générer une exception.

Une implémentation correcte garantit un contrôle fluide des appels sur différents appareils. Testez minutieusement avec différentes surfaces de télécommande.