Core-Telecom

تعمل مكتبة Core-Telecom على تبسيط عملية دمج تطبيق الاتصال بنظام Android من خلال توفير مجموعة قوية ومتسقة من واجهات برمجة التطبيقات.

إذا كنت تريد استكشاف عمليات التنفيذ العملية، يمكنك العثور على نماذج التطبيقات على GitHub:

إعداد 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 لإنشاء دورة حياة المكالمات وإدارتها.

إنشاء مكالمة

يحدّد عنصر 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 وطلبات إعادة الاتصال لإضافة طلب جديد إلى النظام وإدارة تعديلات السطح عن بُعد. يسمح العنصر 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))

إدارة نقاط نهاية الصوت في المكالمات

مراقبة نقاط نهاية الصوت وإدارتها باستخدام currentCallEndpoint availableEndpoints وisMuted Flow ضمن 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 (المستوى 33 لواجهة برمجة التطبيقات في Android 13 والإصدارات الأقدم) أو foregroundtypes (المستوى 34 لواجهة برمجة التطبيقات في Android 14 والإصدارات الأحدث) لتمكين ميزة العمل في المقدّمة.

كجزء من متطلبات التشغيل في المقدّمة، يجب أن ينشر التطبيق إشعارًا ليتمكّن المستخدمون من معرفة أنّ التطبيق يعمل في المقدّمة.

لضمان حصول تطبيقك على الأولوية في التنفيذ في المقدّمة، أنشئ إعلامًا عند إضافة طلب الاتصال بالنظام الأساسي. تتم إزالة الأولوية في المقدّمة عندما ينهي تطبيقك المكالمة أو عندما يصبح الإشعار غير صالح.

مزيد من المعلومات عن الخدمات التي تعمل في المقدّمة

دعم Surface عن بُعد

يمكن للأجهزة البعيدة (الساعات الذكية وسماعات الرأس التي تعمل بالبلوتوث وAndroid Auto) إدارة المكالمات بدون التفاعل المباشر مع الهاتف. يجب أن ينفذ تطبيقك دالات lambda لطلبات إعادة الاتصال (onAnswerCall وonSetCallDisconnected وonSetCallActive onSetCallInactive) المقدَّمة إلى CallsManager.addCall لمعالجة الإجراءات التي تبدأها هذه الأجهزة.

عند حدوث إجراء عن بُعد، يتمّ استدعاء دالة lambda المقابلة.

يشير اكتمال دالة lambda بنجاح إلى أنّه تمت معالجة الأمر. إذا تعذّر تنفيذ الأمر، من المفترض أن تُلقي دالة lambda استثناءً.

يضمن التنفيذ السليم إمكانية التحكّم في المكالمات بسلاسة على جميع الأجهزة. اختبِر الميزة بدقة باستخدام مساحات عرض مختلفة عن بُعد.