Core-Telecom

Core-Telecom 라이브러리는 강력하고 일관된 API 세트를 제공하여 호출 애플리케이션을 Android 플랫폼과 통합하는 프로세스를 간소화합니다.

실용적인 구현을 살펴보려면 GitHub에서 샘플 애플리케이션을 확인하세요.

  • 경량 샘플 앱: Core-Telecom API 사용을 보여주는 최소한의 예시입니다. 기본 개념을 빠르게 이해하는 데 적합합니다.
  • 포괄적인 샘플 앱 (Core-Telecom팀에서 개발): 고급 텔레콤 기능과 권장사항을 보여주는 더 많은 기능이 포함된 애플리케이션입니다. 복잡한 통합 시나리오를 이해하는 데 유용한 리소스입니다.

Core-Telecom 설정

앱의 build.gradle 파일에 androidx.core:core-telecom 종속 항목을 추가합니다.

dependencies {
    implementation ("androidx.core:core-telecom:1.0.0")
}

AndroidManifest.xml에서 MANAGE_OWN_CALLS 권한을 선언합니다.

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

통화 추가

CallAttributesCompat 및 콜백과 함께 callsManager.addCall를 사용하여 시스템에 새 호출을 추가하고 원격 노출 영역 업데이트를 관리합니다. addCall 블록 내의 callControlScope는 주로 앱이 통화 상태를 전환하고 오디오 업데이트를 수신하도록 허용합니다.

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 */ }
}

전화 거부

CallControlScope 내에서 DisconnectCause.REJECTED와 함께 disconnect()를 사용하여 전화를 거부합니다.

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 */ }
}

통화 연결 해제

DisconnectCause와 함께 disconnect()를 사용하여 통화 연결 해제:

disconnect(DisconnectCause(DisconnectCause.LOCAL))

통화 오디오 엔드포인트 관리

CallControlScope 내에서 currentCallEndpoint, availableEndpoints, isMuted Flow를 사용하여 오디오 엔드포인트를 관찰하고 관리합니다.

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 지원

원격 기기 (스마트시계, 블루투스 헤드셋, Android Auto)는 휴대전화와 직접 상호작용하지 않고도 통화 관리를 할 수 있습니다. 앱은 이러한 기기에서 시작된 작업을 처리하기 위해 CallsManager.addCall에 제공된 콜백 람다 (onAnswerCall, onSetCallDisconnected, onSetCallActive, onSetCallInactive)를 구현해야 합니다.

원격 작업이 발생하면 해당 람다가 호출됩니다.

명령어가 처리되었음을 나타내는 람다 신호가 성공적으로 완료되었습니다. 명령어를 실행할 수 없는 경우 람다에서 예외를 발생시켜야 합니다.

올바르게 구현하면 여러 기기에서 원활하게 통화를 제어할 수 있습니다. 다양한 원격 노출 영역에서 철저히 테스트합니다.