A biblioteca Core-Telecom
simplifica o processo de integração do seu aplicativo de chamada
com a plataforma Android, fornecendo um conjunto robusto e consistente
de APIs.
Se você quiser conferir implementações práticas, confira os exemplos de aplicativos no GitHub:
- App leve de exemplo: um exemplo mínimo
que demonstra o uso da API
Core-Telecom
. Ideal para entender rapidamente os conceitos fundamentais. - App de exemplo abrangente (desenvolvido pela equipe de Core-Telecom): um aplicativo com mais recursos que mostra as melhores práticas e funcionalidades avançadas de telecomunicações. Esse é um ótimo recurso para entender cenários de integração complexos.
Configurar o Core-Telecom
Adicione a dependência androidx.core:core-telecom
ao arquivo build.gradle
do app:
dependencies {
implementation ("androidx.core:core-telecom:1.0.0")
}
Declare a permissão MANAGE_OWN_CALLS
no AndroidManifest.xml
:
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
Registrar seu aplicativo
Registre seu app de chamada no Android usando CallsManager
para começar a adicionar
chamadas ao sistema. Ao fazer o registro, especifique os recursos do app (por
exemplo, suporte a áudio e vídeo):
val callsManager = CallsManager(context)
val capabilities: @CallsManager.Companion.Capability Int =
(CallsManager.CAPABILITY_BASELINE or
CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)
callsManager.registerAppWithTelecom(capabilities)
Gerenciamento de chamadas
Use as APIs Core-Telecom para criar e gerenciar o ciclo de vida de uma chamada.
Criar uma ligação
O objeto CallAttributesCompat
define as propriedades de uma chamada única,
que pode ter as seguintes características:
displayName
: nome do autor da chamada.address
: endereço de chamada (por exemplo, número de telefone, link da reunião).direction
: entrada ou saída.callType
: áudio ou vídeo.callCapabilities
: oferece suporte a transferência e retenção.
Confira um exemplo de como criar uma chamada recebida:
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
)
}
Adicionar uma ligação
Use callsManager.addCall
com CallAttributesCompat
e callbacks para adicionar uma
nova chamada ao sistema e gerenciar atualizações de superfície remotas. O callControlScope
no bloco addCall
permite principalmente que o app faça a transição do estado
da chamada e receba atualizações de áudio:
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.
}
Atender uma chamada
Atender uma ligação recebida no CallControlScope
:
when (val result = answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {
is CallControlResult.Success -> { /* Call answered */ }
is CallControlResult.Error -> { /* Handle error */ }
}
Rejeitar uma ligação
Rejeite uma chamada usando disconnect()
com DisconnectCause.REJECTED
no
CallControlScope
:
disconnect(DisconnectCause(DisconnectCause.REJECTED))
Ativar uma chamada de saída
Defina uma chamada de saída como ativa quando a parte remota atender:
when (val result = setActive()) {
is CallControlResult.Success -> { /* Call active */ }
is CallControlResult.Error -> { /* Handle error */ }
}
Colocar uma chamada em espera
Use setInactive()
para colocar uma chamada em espera:
when (val result = setInactive()) {
is CallControlResult.Success -> { /* Call on hold */ }
is CallControlResult.Error -> { /* Handle error */ }
}
Desconectar uma chamada
Desconecte uma chamada usando disconnect()
com um DisconnectCause
:
disconnect(DisconnectCause(DisconnectCause.LOCAL))
Gerenciar endpoints de áudio de chamada
Observar e gerenciar endpoints de áudio usando currentCallEndpoint
,
availableEndpoints
e isMuted
Flow
s no CallControlScope
fun observeAudioStateChanges(callControlScope: CallControlScope) {
with(callControlScope) {
launch { currentCallEndpoint.collect { /* Update UI */ } }
launch { availableEndpoints.collect { /* Update UI */ } }
launch { isMuted.collect { /* Handle mute state */ } }
}
}
Mude o dispositivo de áudio ativo usando requestEndpointChange()
:
coroutineScope.launch {
callControlScope.requestEndpointChange(callEndpoint)
}
Suporte em primeiro plano
A biblioteca usa ConnectionService
(Android 13 API de nível 33 e versões anteriores) ou
foregroundtypes (Android 14 API de nível 34 e mais recentes) para oferecer suporte
ao primeiro plano.
Como parte dos requisitos em primeiro plano, o aplicativo precisa postar uma notificação para que os usuários saibam que ele está em execução em primeiro plano.
Para garantir que o app tenha prioridade de execução em primeiro plano, crie uma notificação depois de adicionar a chamada com a plataforma. A prioridade em primeiro plano é removida quando o app encerra a chamada ou a notificação deixa de ser válida.
Saiba mais sobre os serviços em primeiro plano.
Suporte remoto ao Surface
Dispositivos remotos (smartwatches, fones de ouvido Bluetooth, Android Auto) podem
gerenciar chamadas sem interação direta com o smartphone. O app precisa implementar
lambdas de callback (onAnswerCall
, onSetCallDisconnected
, onSetCallActive
,
onSetCallInactive
) fornecidos para CallsManager.addCall
para processar ações
iniciadas por esses dispositivos.
Quando uma ação remota ocorre, a lambda correspondente é invocada.
A conclusão bem-sucedida da lambda indica que o comando foi processado. Se o comando não puder ser obedecido, o lambda vai gerar uma exceção.
A implementação adequada garante o controle de chamadas perfeito em diferentes dispositivos. Teste completamente com várias superfícies remotas.