ספריית Core-Telecom
מייעלת את תהליך השילוב של האפליקציה הקוראת עם פלטפורמת Android, על ידי מתן קבוצה חזקה ועקבית של ממשקי API.
אם אתם רוצים לבדוק הטמעות מעשיות, תוכלו למצוא אפליקציות לדוגמה ב-GitHub:
- אפליקציית דוגמה קלה – דוגמה מינימלית שממחישה שימוש ב-API של
Core-Telecom
. אידיאלי להבנה מהירה של מושגים בסיסיים. - אפליקציית דוגמה מקיפה (שפותחה על ידי צוות Core-Telecom) – אפליקציה עשירה יותר בתכונות שמציגה פונקציות מתקדמות של שירותי תקשורת ושיטות מומלצות. זהו מקור מצוין להבנת תרחישים מורכבים של שילוב.
הגדרת Core-Telecom
מוסיפים את התלות ב-androidx.core:core-telecom
לקובץ build.gradle
של האפליקציה:
dependencies {
implementation ("androidx.core:core-telecom:1.0.0")
}
מגדירים את ההרשאה MANAGE_OWN_CALLS
ב-AndroidManifest.xml
:
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
רישום האפליקציה
כדי להתחיל להוסיף שיחות למערכת, צריך לרשום את אפליקציית השיחות ב-Android באמצעות CallsManager
. במהלך הרישום, צריך לציין את היכולות של האפליקציה (לדוגמה, תמיכה באודיו ובווידאו):
val callsManager = CallsManager(context)
val capabilities: @CallsManager.Companion.Capability Int =
(CallsManager.CAPABILITY_BASELINE or
CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING)
callsManager.registerAppWithTelecom(capabilities)
ניהול השיחות
שימוש בממשקי Core-Telecom API כדי ליצור ולנהל את מחזור החיים של שיחה.
יצירת שיחה
האובייקט CallAttributesCompat
מגדיר את המאפיינים של קריאה ייחודית, שיכולה להיות בעלת המאפיינים הבאים:
displayName
: שם מבצע הקריאה.address
: כתובת השיחה (לדוגמה, מספר טלפון, קישור לפגישה).direction
: נכנסות או יוצאות.callType
: אודיו או וידאו.callCapabilities
: תמיכה בהעברה ובהחזקה.
דוגמה ליצירת שיחה נכנסת:
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
)
}
הוספת שיחה
אפשר להשתמש ב-callsManager.addCall
עם CallAttributesCompat
ועם קריאות חזרה (callbacks) כדי להוסיף קריאה חדשה למערכת ולנהל עדכונים מרוחקים של ממשק. ה-callControlScope
בתוך הבלוק addCall
מאפשר לאפליקציה לשנות את מצב השיחה ולקבל עדכוני אודיו:
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.
}
מענה לשיחה
מענה לשיחה נכנסת בתוך CallControlScope
:
when (val result = answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {
is CallControlResult.Success -> { /* Call answered */ }
is CallControlResult.Error -> { /* Handle error */ }
}
דחיית שיחה
דחיית שיחה באמצעות disconnect()
עם DisconnectCause.REJECTED
בתוך CallControlScope
:
disconnect(DisconnectCause(DisconnectCause.REJECTED))
הפעלת שיחה יוצאת
מגדירים שיחה יוצאת כפעילה ברגע שהצד השני עונה:
when (val result = setActive()) {
is CallControlResult.Success -> { /* Call active */ }
is CallControlResult.Error -> { /* Handle error */ }
}
העברת שיחה להמתנה
כדי להעביר שיחה למצב המתנה, מקישים על setInactive()
:
when (val result = setInactive()) {
is CallControlResult.Success -> { /* Call on hold */ }
is CallControlResult.Error -> { /* Handle error */ }
}
ניתוק שיחה
כדי לנתק שיחה באמצעות disconnect()
עם DisconnectCause
:
disconnect(DisconnectCause(DisconnectCause.LOCAL))
ניהול נקודות קצה של אודיו בשיחות
מעקב אחרי נקודות קצה של אודיו וניהול שלהן באמצעות Flow
של currentCallEndpoint
, availableEndpoints
ו-isMuted
ב-CallControlScope
fun observeAudioStateChanges(callControlScope: CallControlScope) {
with(callControlScope) {
launch { currentCallEndpoint.collect { /* Update UI */ } }
launch { availableEndpoints.collect { /* Update UI */ } }
launch { isMuted.collect { /* Handle mute state */ } }
}
}
משנים את התקן האודיו הפעיל באמצעות requestEndpointChange()
:
coroutineScope.launch {
callControlScope.requestEndpointChange(callEndpoint)
}
תמיכה בחזית
הספרייה משתמשת ב-ConnectionService
(Android 13 API ברמה 33 ומטה) או ב-foregroundtypes (Android 14 API ברמה 34 ואילך) לתמיכה בחזית.
כחלק מדרישות הפעילות בחזית, האפליקציה חייבת לפרסם התראה כדי שהמשתמשים ידעו שהיא פועלת בחזית.
כדי להבטיח שהאפליקציה תקבל עדיפות ביצוע בחזית, צריך ליצור התראה אחרי שמוסיפים את הקריאה לפלטפורמה. העדיפות בחזית תוסר כשהאפליקציה תסיים את השיחה או שההתראה לא תהיה תקפה יותר.
תמיכה מרחוק ב-Surface
מכשירים מרוחקים (שעונים חכמים, אוזניות Bluetooth, Android Auto) יכולים לנהל שיחות בלי אינטראקציה ישירה עם הטלפון. האפליקציה צריכה להטמיע פונקציות callback מסוג lambda (onAnswerCall
, onSetCallDisconnected
, onSetCallActive
, onSetCallInactive
) שסופקו ל-CallsManager.addCall
כדי לטפל בפעולות שהמכשירים האלה יוזמנו.
כשמתרחשת פעולה מרחוק, הפונקציה Lambda המתאימה מופעלת.
השלמת ה-lambda בהצלחה מסמנת שהפקודה טופלה. אם אי אפשר לבצע את הפקודה, הפונקציה Lambda צריכה להוציא חריגה.
הטמעה נכונה מבטיחה שליטה חלקה בשיחות במכשירים שונים. כדאי לבדוק היטב עם משטחים שונים מרחוק.