Core-Telecom
kitaplığı, güçlü ve tutarlı bir API grubu sağlayarak arama uygulamanızı Android platformuyla entegre etme sürecini kolaylaştırır.
Pratik uygulamaları keşfetmek istiyorsanız GitHub'da örnek uygulamalar bulabilirsiniz:
- Hafif Örnek Uygulama:
Core-Telecom
API kullanımını gösteren minimal bir örnek. Temel kavramları hızlı bir şekilde anlamak için idealdir. - Kapsamlı Örnek Uygulama (Core-Telecom Ekibi tarafından geliştirilmiştir): Gelişmiş telekom işlevlerini ve en iyi uygulamaları gösteren, daha fazla özellik barındıran bir uygulamadır. Bu, karmaşık entegrasyon senaryolarını anlamanıza yardımcı olacak mükemmel bir kaynaktır.
Core-Telecom'u kurma
androidx.core:core-telecom
bağımlılığını uygulamanızın build.gradle
dosyasına ekleyin:
dependencies {
implementation ("androidx.core:core-telecom:1.0.0")
}
AndroidManifest.xml
dosyanızda MANAGE_OWN_CALLS
iznini beyan edin:
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
Uygulamanızı kaydettirme
Sisteme arama eklemeye başlamak için CallsManager
kullanarak arama uygulamanızı Android'e kaydedin. Kaydolurken uygulamanızın özelliklerini (ör. ses, video desteği) belirtin:
val callsManager = CallsManager(context)
val capabilities: @CallsManager.Companion.Capability Int =
(CallsManager.CAPABILITY_BASELINE or
CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)
callsManager.registerAppWithTelecom(capabilities)
Çağrı Yönetimi
Arama yaşam döngüsü oluşturmak ve yönetmek için Core-Telecom API'lerini kullanın.
Görüşme oluşturma
CallAttributesCompat
nesnesi, aşağıdaki özelliklere sahip olabilecek benzersiz bir aramanın özelliklerini tanımlar:
displayName
: Arayan kişinin adı.address
: Arama adresi (ör. telefon numarası, toplantı bağlantısı).direction
: Gelen veya giden.callType
: Ses veya video.callCapabilities
: Aktarım ve bekletme işlemlerini destekler.
Aşağıda, gelen arama oluşturma örneği verilmiştir:
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
)
}
Görüşme ekleme
Sisteme yeni bir çağrı eklemek ve uzak yüzey güncellemelerini yönetmek için CallAttributesCompat
ile callsManager.addCall
ve geri çağırma işlevini kullanın. addCall
bloğu içindeki callControlScope
, öncelikle uygulamanızın arama durumunu değiştirmesine ve ses güncellemeleri almasına olanak tanır:
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.
}
Çağrı yanıtlama
CallControlScope
içinde gelen aramayı yanıtlama:
when (val result = answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {
is CallControlResult.Success -> { /* Call answered */ }
is CallControlResult.Error -> { /* Handle error */ }
}
Aramayı reddetme
CallControlScope
içinde DisconnectCause.REJECTED
ile disconnect()
kullanarak aramayı reddetme:
disconnect(DisconnectCause(DisconnectCause.REJECTED))
Giden aramayı etkinleştirme
Uzak taraf yanıt verdikten sonra giden aramayı etkin olarak ayarlama:
when (val result = setActive()) {
is CallControlResult.Success -> { /* Call active */ }
is CallControlResult.Error -> { /* Handle error */ }
}
Çağrıyı beklemeye alma
Bir aramayı beklemeye almak için setInactive()
simgesini kullanın:
when (val result = setInactive()) {
is CallControlResult.Success -> { /* Call on hold */ }
is CallControlResult.Error -> { /* Handle error */ }
}
Bir aramanın bağlantısını kesme
DisconnectCause
ile disconnect()
kullanarak bir görüşmenin bağlantısını kesme:
disconnect(DisconnectCause(DisconnectCause.LOCAL))
Görüşme ses uç noktalarını yönetme
CallControlScope
içinde currentCallEndpoint
, availableEndpoints
ve isMuted
Flow
'ları kullanarak ses uç noktalarını gözlemleyin ve yönetin
fun observeAudioStateChanges(callControlScope: CallControlScope) {
with(callControlScope) {
launch { currentCallEndpoint.collect { /* Update UI */ } }
launch { availableEndpoints.collect { /* Update UI */ } }
launch { isMuted.collect { /* Handle mute state */ } }
}
}
requestEndpointChange()
simgesini kullanarak etkin ses cihazını değiştirin:
coroutineScope.launch {
callControlScope.requestEndpointChange(callEndpoint)
}
Ön plan desteği
Kitaplık, ön plan desteği için ConnectionService
(Android 13 API düzeyi 33 ve önceki sürümler) veya foregroundtypes (Android 14 API düzeyi 34 ve sonraki sürümler) kullanır.
Ön plan şartları kapsamında, uygulamanın ön planda çalıştığının kullanıcılara bildirilmesi için uygulamanın bir bildirim yayınlaması gerekir.
Uygulamanızın ön planda yürütme önceliğine sahip olmasını sağlamak için platformla aramayı ekledikten sonra bir bildirim oluşturun. Uygulamanız aramayı sonlandırdığında veya bildiriminiz artık geçerli olmadığında ön plan önceliği kaldırılır.
Ön plan hizmetleri hakkında daha fazla bilgi edinin.
Uzaktan Surface desteği
Uzaktan cihazlar (akıllı saatler, Bluetooth kulaklıklar, Android Auto), doğrudan telefon etkileşimi olmadan arama yönetimi yapabilir. Uygulamanız, bu cihazlar tarafından başlatılan işlemleri işlemek için CallsManager.addCall
'e sağlanan geri çağırma lambdalarını (onAnswerCall
, onSetCallDisconnected
, onSetCallActive
, onSetCallInactive
) uygulamalıdır.
Uzaktan bir işlem gerçekleştiğinde ilgili lambda çağrılır.
Lambda'nın başarıyla tamamlanması, komutun işlendiğini gösterir. Komuta uyulamıyorsa lambda bir istisna atmalıdır.
Doğru şekilde uygulandığında, farklı cihazlarda sorunsuz görüşme kontrolü sağlar. Çeşitli uzaktan kumanda yüzeyleriyle ayrıntılı olarak test edin.
Telefon araması uzantıları
Kitaplık, aramalarınızın arama durumunu ve ses yolunu yönetmenin yanı sıra Android Auto gibi uzak yüzeylerde daha zengin bir arama deneyimi için uygulamanızın uygulayabileceği isteğe bağlı özellikler olan arama uzantılarını da destekler. Toplantı odaları, görüşme sessize alma ve ek görüşme simgeleri bu özellikler arasındadır. Uygulamanız bir uzantı uyguladığında, uygulamanın sağladığı bilgiler, bu uzantıların kullanıcı arayüzünde gösterilmesini de destekleyen tüm bağlı cihazlarla senkronize edilir. Bu, kullanıcıların etkileşimde bulunabileceği uzak cihazlarda da bu özelliklerin kullanılabileceği anlamına gelir.
Uzantılarla Arama Oluşturma
Arama oluştururken CallManager#addCall
yerine CallManager#addCallWithExtensions'i kullanabilirsiniz. Bu yöntem, uygulamaya ExtensionInitializationScope
adlı farklı bir kapsama erişim sağlar. Bu kapsam, uygulamanın desteklediği isteğe bağlı uzantı grubunu başlatmasına olanak tanır. Ayrıca bu kapsam, uzantı özelliği değişimi ve başlatma işlemi tamamlandıktan sonra uygulamaya geri dönen CallControlScope
sağlayan onCall
adlı ek bir yöntem sağlar.
scope.launch {
mCallsManager.addCallWithExtensions(
attributes,
onAnswer,
onDisconnect,
onSetActive,
onSetInactive
) {
// Initialize extension-specific code...
// After the call has been initialized, perform in-call actions
onCall {
// Example: process call state updates
callStateFlow.onEach { newState ->
// handle call state updates and notify telecom
}.launchIn(this)
// Use initialized extensions...
}
}
}
Destek Görüşmesi Katılımcıları
Uygulamanız toplantılar veya grup görüşmeleri için görüşme katılımcılarını destekliyorsa bu uzantıyı desteklediğini beyan etmek için addParticipantExtension
'ü kullanın ve katılımcılar değiştiğinde uzak yüzeyleri güncellemek için ilgili API'leri kullanın.
mCallsManager.addCallWithExtensions(...) {
// Initialize extensions...
// Notifies Jetpack that this app supports the participant
// extension and provides the initial participants state in the call.
val participantExtension = addParticipantExtension(
initialParticipants,
initialActiveParticipant
)
// After the call has been initialized, perform in-call control actions
onCall {
// other in-call control and extension actions...
// Example: update remote surfaces when the call participants change
participantsFlow.onEach { newParticipants ->
participantExtension.updateParticipants(newParticipants)
}.launchIn(this)
}
}
Uzak yüzeyleri görüşmedeki katılımcılar hakkında bilgilendirmenin yanı sıra ParticipantExtension#updateActiveParticipant
kullanılarak etkin katılımcı da güncellenebilir.
Ayrıca, görüşmedeki katılımcılarla ilgili isteğe bağlı işlemler için de destek vardır.
Uygulama, katılımcıların görüşmede söz isteme özelliğini kullanabilmesini sağlamak ve söz isteyen diğer katılımcıları görmek için ParticipantExtension#addRaiseHandSupport
'ü kullanabilir.
mCallsManager.addCallWithExtensions(...) {
// Initialize extensions...
// Notifies Jetpack that this app supports the participant
// extension and provides the initial list of participants in the call.
val participantExtension = addParticipantExtension(initialParticipants)
// Notifies Jetpack that this app supports the notion of participants
// being able to raise and lower their hands.
val raiseHandState = participantExtension.addRaiseHandSupport(
initialRaisedHands
) { onHandRaisedStateChanged ->
// handle this user's raised hand state changed updates from
// remote surfaces.
}
// After the call has been initialized, perform in-call control actions
onCall {
// other in-call control and extension actions...
// Example: update remote surfaces when the call participants change
participantsFlow.onEach { newParticipants ->
participantExtension.updateParticipants(newParticipants)
}.launchIn(this)
// notify remote surfaces of which of the participants have their
// hands raised
raisedHandsFlow.onEach { newRaisedHands ->
raiseHandState.updateRaisedHands(newRaisedHands)
}.launchIn(this)
}
}
Destek aramasını sessize alma
Arama sessize alma özelliği, kullanıcının cihazın mikrofonunu fiziksel olarak kapatmadan uygulamanın aramanın giden sesini kapatmasını istemesine olanak tanır. Bu özellik arama başına yönetilir. Bu nedenle Jetpack, VOIP araması etkinken devam eden hücresel aramaların dünya genelindeki sessize alma durumunu yönetmenin karmaşıklığını ele alır. Bu sayede, giden sesin kapatılması çoklu görüşme senaryolarında daha az hataya yol açar. Ayrıca, kullanıcı görüşmenin sessiz olduğunu fark etmeden konuşurken "konuşuyor musunuz?" gibi faydalı özellikler sunar.
mCallsManager.addCallWithExtensions(...) {
// Initialize extensions...
// Add support for locally silencing the call's outgoing audio and
// register a handler for when the user changes the call silence state
// from a remote surface.
val callSilenceExtension = addLocalCallSilenceExtension(
initialCallSilenceState = false
) { newCallSilenceStateRequest ->
// handle the user's request to enable/disable call silence from
// a remote surface
}
// After the call has been initialized, perform in-call control actions
onCall {
// other in-call control and extension actions...
// When the call's call silence state changes, update remote
// surfaces of the new state.
callSilenceState.onEach { isSilenced ->
callSilenceExtension.updateIsLocallySilenced(isSilenced)
}.launchIn(this)
}
}
Destek Araması Simgeleri
Çağrı simgesi, uygulamanın çağrı sırasında uzak yüzeylerde gösterilecek çağrıyı temsil eden özel bir simge belirtmesine olanak tanır. Bu simge, aramanın süresi boyunca da güncellenebilir.
mCallsManager.addCallWithExtensions(...) {
// Initialize extensions...
// Add support for a custom call icon to be displayed during the
// lifetime of the call.
val callIconExtension = addCallIconExtension(
initialCallIconUri = initialUri
)
// After the call has been initialized, perform in-call control actions
onCall {
// other in-call control and extension actions...
// When the call's icon changes, update remote surfaces by providing
// the new URI.
callIconUri.onEach { newIconUri ->
callIconExtension.updateCallIconUri(newIconUri)
}.launchIn(this)
}
}