Core-Telecom

Core-Telecom ライブラリは、堅牢で一貫した API セットを提供することで、呼び出し元のアプリと Android プラットフォームの統合プロセスを効率化します。

実用的な実装を確認するには、GitHub でサンプル アプリケーションをご覧ください。

Core-Telecom を設定する

アプリの build.gradle ファイルに androidx.core:core-telecom 依存関係を追加します。

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

AndroidManifest.xmlMANAGE_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
    )
}

通話を追加する

callsManager.addCallCallAttributesCompat とコールバックとともに使用して、システムに新しい呼び出しを追加し、リモート サーフェスの更新を管理します。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 */ }
}

通話を切る

disconnect() を使用して通話を終了し、DisconnectCause で通話を再開します。

disconnect(DisconnectCause(DisconnectCause.LOCAL))

通話音声エンドポイントを管理する

CallControlScope 内の currentCallEndpointavailableEndpointsisMuted 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 以降)を使用します。

フォアグラウンドの要件の一部として、アプリがフォアグラウンドで実行されていることをユーザーに知らせるために、アプリは通知を投稿する必要があります。

アプリがフォアグラウンド実行の優先度を取得するようにするには、プラットフォームでの呼び出しを追加したら通知を作成します。アプリが呼び出しを終了するか、通知が有効でなくなった場合、フォアグラウンドの優先度は削除されます。

詳しくは、フォアグラウンド サービスについての記事をご覧ください。

リモート サーフェスのサポート

リモート デバイス(スマートウォッチ、Bluetooth ヘッドセット、Android Auto)は、スマートフォンを直接操作しなくても通話を管理できます。アプリは、これらのデバイスによって開始されたアクションを処理するために、CallsManager.addCall に提供されるコールバック ラムダ(onAnswerCallonSetCallDisconnectedonSetCallActiveonSetCallInactive)を実装する必要があります。

リモート アクションが発生すると、対応するラムダが呼び出されます。

Lambda の正常な完了は、コマンドが処理されたことを示します。コマンドを実行できない場合は、ラムダは例外をスローする必要があります。

適切に実装すると、さまざまなデバイスでシームレスに通話コントロールできます。さまざまなリモート サーフェスでテストを徹底します。