새로운 Android Telecom Jetpack 라이브러리를 사용하면 통화 상태를 플랫폼에 쉽게 알릴 수 있습니다. GitHub에서 소스 코드와 샘플 앱을 찾을 수 있습니다.
종속 항목 및 권한
먼저 앱 모듈 build.gradle 파일을 열고 androidx Telecom 모듈의 종속 항목을 추가합니다.
dependencies {
implementation ("androidx.core:core-telecom:1.0.0-alpha02")
}
앱 매니페스트에서 앱이 MANAGE_OWN_CALLS
권한을 사용한다고 선언합니다.
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
애플리케이션 등록
Android에 앱에 관해 알리려면 앱과 앱의 기능을 등록해야 합니다. 이를 통해 영상 통화, 통화 스트리밍, 통화 대기 등 앱이 지원하는 기능이 Android에 무엇인지 알 수 있습니다. 이 정보는 Android에서 앱의 기능을 사용하도록 자체적으로 구성하는 데 중요합니다.
private val callsManager = CallsManager(context)
var capabilities: @CallsManager.Companion.Capability Int =
CallsManager.CAPABILITY_BASELINE or
CallsManager.CAPABILITY_SUPPORTS_CALL_STREAMING or
CallsManager.CAPABILITY_SUPPORTS_VIDEO_CALLING
callsManager.registerAppWithTelecom(capabilities)
플랫폼 통합
통화 애플리케이션에서 가장 일반적인 두 가지 통화 시나리오는 수신 전화와 발신 전화입니다. 호출 방향을 올바르게 등록하고 사용자에게 알림을 적절하게 알리려면 아래 API를 사용하세요.
통화 등록
이 예에서는 수신 전화를 등록하는 방법을 보여줍니다.
companion object {
const val APP_SCHEME = "MyCustomScheme"
const val ALL_CALL_CAPABILITIES = (CallAttributes.SUPPORTS_SET_INACTIVE
or CallAttributes.SUPPORTS_STREAM or CallAttributes.SUPPORTS_TRANSFER)
const val INCOMING_NAME = "Luke"
val INCOMING_URI: Uri = Uri.fromParts(APP_SCHEME, "", "")
// Define all possible properties for CallAttributes
val INCOMING_CALL_ATTRIBUTES =
CallAttributes(
INCOMING_NAME,
INCOMING_URI,
DIRECTION_INCOMING,
CALL_TYPE_VIDEO_CALL,
ALL_CALL_CAPABILITIES)
}
callAttributes
객체에는 다음 속성이 포함될 수 있습니다.
displayName
: 발신자, 회의 또는 세션의 이름입니다.address
: 호출의 주소입니다. 이는 회의 링크로 확장할 수 있습니다.direction
: 수신 또는 발신과 같은 통화의 방향입니다.callType
: 동영상, 오디오 등 전송 중인 데이터와 관련된 정보입니다.callCapabilities
: 호출 기능을 지정하는 객체입니다.
callCapabilities
객체에는 다음 속성이 포함될 수 있습니다.
streaming
: 통화가 다른 Android 지원 기기로 오디오 스트리밍을 지원하는지 여부를 나타냅니다.transfer
: 통화를 전달할 수 있는지를 나타냅니다.hold
: 통화를 대기할 수 있는지 여부를 나타냅니다.
통화 추가
기기가 텔레콤을 지원하지 않거나 통화를 설정할 때 오류가 발생하면 addCall()
메서드는 예외를 반환합니다.
try {
callsManager.addCall(
INCOMING_CALL_ATTRIBUTES,
onIsCallAnswered, // Watch needs to know if it can answer the call
onIsCallDisconnected,
onIsCallActive,
onIsCallInactive
) {
callControlScope = this
}
}
전화 받기
수신 전화를 걸면 전화를 받거나 거부해야 합니다. 이 시험은 전화를 받는 방법을 보여줍니다.
when (answer(CallAttributesCompat.CALL_TYPE_AUDIO_CALL)) {
is CallControlResult.Success -> {
}
is CallControlResult.Error -> {
}
}
다른 통화가 진행 중이면 answer()
는 CallControlResult.Error
를 반환하여 통화에 응답할 수 없는 이유를 알려줍니다. 이 경우 사용자는 다른 통화를 대기 상태로 전환해야 합니다.
통화 거부
전화를 거부하려면 DisconnectCause.Rejected
로 통화를 끊으세요.
fun onRejectCall(){
coroutineScope.launch {
callControlScope?.let {
it.disconnect(DisconnectCause(DisconnectCause.REJECTED))
}
}
}
발신 전화
발신 전화를 걸 때 원격 당사자가 전화를 받으면 호출을 active로 설정하여 플랫폼이 통화가 진행 중임을 인식하도록 해야 합니다.
when (setActive()) {
is CallControlResult.Success -> {
onIsCallActive()
}
is CallControlResult.Error -> {
updateCurrentCall {
copy(errorCode = result.errorCode)
}
}
}
통화를 대기 상태로 전환
통화 앱에서 통화 대기를 지원하는 경우 setInActive
를 사용하여 통화가 활성화되지 않았으며 다른 앱에서 마이크와 카메라를 자유롭게 사용할 수 있다고 플랫폼에 알립니다.
when (setInActive()) {
is CallControlResult.Success -> {
}
is CallControlResult.Error -> {
updateCurrentCall {
copy(errorCode = result.errorCode)
}
}
}
연결 해제
통화 연결을 끊으려면 유효한 원인을 제공하여 텔레콤 스택에 연결을 해제하도록 알립니다.
coroutineScope.launch {
callControlScope?.disconnect(DisconnectCause(DisconnectCause.LOCAL))
}
오디오 라우팅
통화 중에 사용자가 스피커, 스피커, 블루투스 기기와 같은 기기 간에 전환하는 경우가 있습니다. availableEndpoints
및 currentCallEndpoint
API를 사용하여 사용자가 사용할 수 있는 모든 기기 목록과 활성 기기를 가져옵니다.
이 예에서는 두 흐름을 결합하여 사용자에게 기기 목록과 활성 상태의 기기를 표시할 UI 객체를 만듭니다.
availableEndpoint = combine(callControlScope.availableEndpoints,
callControlScope.currentCallEndpoint) {
availableDevices: List<CallEndpoint>, activeDevice : CallEndpoint ->
availableDevices.map {
EndPointUI(
isActive = activeDevice.endpointName == it.endpointName, it
)
}
}
활성 기기를 변경하려면 변경하려는 CallEndpoint
와 함께 requestEndpointChange
를 사용합니다.
coroutineScope.launch {
callControlScope?.requestEndpointChange(callEndpoint)
}
을 사용하도록 미디어 스트림을 구성해야 합니다.
포그라운드 지원
텔레콤 라이브러리는 포그라운드 지원이 제공됩니다. 이 라이브러리는 Android 13 및 이전 버전을 실행하는 기기에 ConnectionService
를 사용합니다. Android 14 이상에서는 foregroundtypes 마이크와 카메라를 사용하여 포그라운드 서비스를 올바르게 지원합니다. 포그라운드 서비스 자세히 알아보기
포그라운드 요구사항의 일부로 애플리케이션은 사용자에게 애플리케이션이 포그라운드에서 실행 중임을 알 수 있도록 알림을 게시해야 합니다.
앱이 포그라운드 실행 우선순위를 받도록 하려면 플랫폼에 호출을 등록한 후 알림을 만듭니다. 앱이 통화를 종료하거나 알림이 더 이상 유효하지 않으면 포그라운드 우선순위가 삭제됩니다.
is TelecomCall.Registered -> {
val notification = createNotification(call)
notificationManager.notify(TELECOM_NOTIFICATION_ID, notification)
}
표면 지원
시계에 일반 엔드포인트 수신기 애플리케이션이 있습니다. 이 애플리케이션은 사용자에게 전화 받기, 거부, 연결 해제와 같은 기본 인터페이스를 제공합니다. 애플리케이션은 기기에서 작업을 실행했음을 플랫폼에 알리는 람다 함수를 구현하여 이러한 작업을 지원합니다.
애플리케이션이 응답하지 않으면 각 람다 함수는 5초 후에 타임아웃되며 트랜잭션이 실패합니다.
callsManager.addCall(
attributes,
onIsCallAnswered, // Watch/Auto need to know if they can answer the call
onIsCallDisconnected,
onIsCallActive,
onIsCallInactive
) {
//Call Scope
}
/**
* Can the call be successfully answered??
* TIP: Check the connection/call state to see if you can answer a call
* Example you may need to wait for another call to hold.
**/
val onIsCallAnswered: suspend(type: Int) -> Unit = {}
/**
* Can the call perform a disconnect
*/
val onIsCallDisconnected: suspend (cause: DisconnectCause) -> Unit = {}
/**
* Check is see if you can make the call active.
* Other calls and state might stop us from activating the call
*/
val onIsCallActive: suspend () -> Unit = {
updateCurrentCall {
}
}
/**
* Check to see if you can make the call inactivate
*/
val onIsCallInactive: suspend () -> Unit = {}