Core-Telecom

کتابخانه Core-Telecom فرآیند ادغام برنامه تماس شما با پلتفرم اندروید را با ارائه مجموعه ای قوی و سازگار از APIها ساده می کند.

اگر می خواهید پیاده سازی های عملی را کاوش کنید، می توانید نمونه برنامه های کاربردی را در 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" />

اپلیکیشن خود را ثبت کنید

برنامه تماس خود را با استفاده از CallsManager در Android ثبت کنید تا شروع به افزودن تماس به سیستم کنید. هنگام ثبت نام، قابلیت های برنامه خود را مشخص کنید (به عنوان مثال، پشتیبانی صوتی، تصویری):

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))

نقاط پایانی صوتی تماس را مدیریت کنید

مشاهده و مدیریت نقاط انتهایی صوتی با استفاده از 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 (Android 13 API سطح 33 و پایین تر) یا پیش زمینه (Android 14 API سطح 34 و بالاتر) برای پشتیبانی پیش زمینه استفاده می کند.

به عنوان بخشی از الزامات پیش زمینه، برنامه باید یک اعلان ارسال کند تا کاربران بدانند که برنامه در پیش زمینه در حال اجرا است.

برای اطمینان از اینکه برنامه شما اولویت اجرای پیش زمینه را دارد، پس از افزودن تماس با پلتفرم، یک اعلان ایجاد کنید. وقتی برنامه شما تماس را قطع می کند یا اعلان شما دیگر معتبر نیست، اولویت پیش زمینه حذف می شود.

درباره خدمات پیش زمینه بیشتر بیاموزید .

پشتیبانی از Remote Surface

دستگاه های راه دور (ساعت های هوشمند، هدست های بلوتوث، Android Auto) قادر به مدیریت تماس بدون تعامل مستقیم با تلفن هستند. برنامه شما باید لامبداهای پاسخ به تماس ( onAnswerCall ، onSetCallDisconnected ، onSetCallActive ، onSetCallInactive ) ارائه شده به CallsManager.addCall را برای مدیریت اقدامات آغاز شده توسط این دستگاه‌ها اجرا کند.

هنگامی که یک عمل از راه دور رخ می دهد، لامبدا مربوطه فراخوانی می شود.

تکمیل موفقیت آمیز لامبدا نشان می دهد که دستور پردازش شده است. اگر فرمان قابل اطاعت نباشد، لامبدا باید یک استثنا بیاندازد.

اجرای صحیح کنترل تماس بدون درز را در دستگاه های مختلف تضمین می کند. به طور کامل با سطوح مختلف از راه دور تست کنید.

برنامه های افزودنی تماس

این کتابخانه علاوه بر مدیریت وضعیت تماس و مسیر صوتی تماس‌های شما، از برنامه‌های افزودنی تماس نیز پشتیبانی می‌کند، که ویژگی‌های اختیاری هستند که برنامه شما می‌تواند برای تجربه تماس غنی‌تر در سطوح از راه دور، مانند Android Auto، پیاده‌سازی کند. این ویژگی‌ها شامل اتاق‌های جلسه، سکوت تماس و نمادهای تماس اضافی است. هنگامی که برنامه شما یک برنامه افزودنی را پیاده سازی می کند، اطلاعاتی که برنامه ارائه می کند با همه دستگاه های متصل که از نمایش این افزونه ها در رابط کاربری خود نیز پشتیبانی می کنند، همگام می شود. این بدان معنی است که این ویژگی ها در دستگاه های راه دور نیز برای تعامل کاربران در دسترس خواهد بود.

ایجاد تماس با برنامه های افزودنی

هنگام ایجاد تماس، به جای استفاده از CallManager#addCall برای ایجاد تماس، می‌توانید به جای آن از CallManager#addCallWithExtensions استفاده کنید که به برنامه اجازه می‌دهد به محدوده دیگری به نام ExtensionInitializationScope دسترسی داشته باشد. این محدوده به برنامه اجازه می دهد تا مجموعه پسوندهای اختیاری را که پشتیبانی می کند مقداردهی اولیه کند. علاوه بر این، این محدوده یک روش اضافی به نام onCall را ارائه می دهد که پس از تبادل قابلیت برنامه افزودنی و تکمیل اولیه، یک CallControlScope به برنامه برمی گرداند.

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...
        }
    }
}

از شرکت کنندگان در تماس پشتیبانی کنید

اگر برنامه شما از تماس شرکت‌کنندگان برای جلسات یا تماس‌های گروهی پشتیبانی می‌کند، از addParticipantExtension برای اعلام پشتیبانی از این برنامه افزودنی استفاده کنید و از APIهای مرتبط برای به‌روزرسانی سطوح راه دور هنگام تغییر شرکت‌کنندگان استفاده کنید.

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)
        }
    }

همراه با اطلاع رسانی به سطوح راه دور از شرکت کنندگان در تماس، شرکت کننده فعال همچنین می تواند با استفاده از ParticipantExtension#updateActiveParticipant به روز شود.

همچنین از اقدامات اختیاری مربوط به شرکت کنندگان در تماس پشتیبانی می شود. این برنامه می‌تواند از ParticipantExtension#addRaiseHandSupport استفاده کند تا از تصور شرکت‌کنندگانی که در تماس دست خود را بالا می‌برند حمایت کند و ببیند کدام شرکت‌کننده دیگر نیز دست‌هایشان را بالا می‌برند.

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)
        }
    }

پشتیبانی از سکوت تماس

بی‌صدا کردن تماس به کاربر این امکان را می‌دهد تا بدون قطع فیزیکی میکروفون دستگاه، از برنامه درخواست کند صدای خروجی تماس را بی‌صدا کند. این ویژگی در هر تماس مدیریت می‌شود، بنابراین Jetpack پیچیدگی مدیریت وضعیت بی‌صدا جهانی تماس‌های تلفن همراه در حال انجام را در زمانی که تماس VOIP فعال است، کنترل می‌کند. این امر باعث می‌شود که خاموش کردن صدای خروجی در سناریوهای چند تماس کمتر دچار خطا شود و همچنین ویژگی‌های مفیدی مانند نشانه‌های «آیا صحبت می‌کنید» را در زمانی که کاربر صحبت می‌کند در حالی که متوجه نمی‌شود که سکوت تماس فعال است، امکان‌پذیر است.

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)
        }
    }

پشتیبانی از نمادهای تماس

یک نماد تماس به برنامه اجازه می‌دهد یک نماد سفارشی که نشان دهنده تماس است را مشخص کند تا در سطوح از راه دور در طول تماس نمایش داده شود. این نماد همچنین می تواند در طول عمر تماس به روز شود.

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)
        }
    }