Kotlin

通話管理

電話を受ける

つの新しいプロパティを追加する onGoingCallID 現在のライブコールを保持し callInviteID の上部で着信招待を保留する。 MainActivity クラスである:

private var onGoingCallID: CallId? = null
private var callInviteID: CallId? = null

着信を聞くには、コール・インビテーション・リスナーを onCreate メソッド MainActivity クラスである:

client.setCallInviteListener { callId, from, channelType ->
  callInviteID = callId
  runOnUiThread {
    answerCallButton.visibility = View.VISIBLE
    rejectCallButton.visibility = View.VISIBLE
    endCallButton.visibility = View.GONE
  }
}

アプリは着信イベントをリッスンします。上記のコードでは、着信イベントを受信すると、応答ボタンと着信拒否ボタンが表示されます。以下のように callInviteID を参照し、後でコールとやりとりする。

次に、コールインビテーションリスナーの下に、オンRTCハングアップリスナーを追加する。

client.setOnCallHangupListener { callId, callQuality, isRemote ->
  onGoingCallID = null
  answerCallButton.visibility = View.GONE
  rejectCallButton.visibility = View.GONE
  endCallButton.visibility = View.GONE
}

UIを使ってアクションを実行する前に、ボタンにリスナーを追加する必要があります。このコードを onCreate 内部 MainActivity クラスである:

answerCallButton.setOnClickListener { answerCall() }
rejectCallButton.setOnClickListener { rejectCall() }
endCallButton.setOnClickListener { endCall() }

電話に出るには answerCall メソッド MainActivity クラスである:

@SuppressLint("MissingPermission")
private fun answerCall() {
  callInviteID?.let {
    client.answer(it) {
      err ->
      when {
        err != null -> {
          connectionStatusTextView.text = err.localizedMessage
        }
        else -> {
          onGoingCallID = it
          answerCallButton.visibility = View.GONE
          rejectCallButton.visibility = View.GONE
          endCallButton.visibility = View.VISIBLE
        }
      }
    }
  }
}

電話に出た後 end call ボタンが表示されます。

注: について SuppressLint アノテーションを使用しています。本番アプリでは、呼び出しに応答する前にパーミッションが付与されていることを確認する必要があります。

通話を拒否するには rejectCall メソッド MainActivity クラスである:

private fun rejectCall() {
    callInviteID?.let {
      client.reject(it) { err ->
        when {
          err != null -> {
            connectionStatusTextView.text = err.localizedMessage
          }
          else -> {
            answerCallButton.visibility = View.GONE
            rejectCallButton.visibility = View.GONE
            endCallButton.visibility = View.GONE
          }
        }
      }
    onGoingCallID = null
  }
}

通話を終了するには endCall メソッド MainActivity クラスである:

private fun endCall() {
  onGoingCallID?.let {
    client.hangup(it) {
      err ->
      when {
        err != null -> {
          connectionStatusTextView.text = err.localizedMessage
        }
        else -> {
          answerCallButton.visibility = View.GONE
          rejectCallButton.visibility = View.GONE
          endCallButton.visibility = View.GONE
        }
      }
    }
  }
  onGoingCallID = null
}

着信拒否または通話終了に成功した後、次のように設定することに注意。 call プロパティの値をnullに戻す。

ビルド&ラン

前のステップで構築したウェブフック・サーバーがまだ稼働していることを確認してください。

を押す。 Ctrl + R キーでアプリをビルドして実行する。Numbersに電話する。

先のステップで申請した番号に電話をかける。

ウェブフック

通話を続けながら、端末に切り替えてください。 /voice/answer NCCO を取得するために呼び出されるエンドポイント:

NCCO request: - caller: 447700900000 - callee: 442038297050

また、通話がさまざまな段階を経て進むにつれて、 /voice/event が送られる:

EVENT:
{
  headers: {},
  from: '447700900000',
  to: '442038297050',
  uuid: '0779a56d002f1c7f47f82ef5fe84ab79',
  conversation_uuid: 'CON-8f5a100c-fbce-4218-8d4b-16341335bcd6',
  status: 'ringing',
  direction: 'inbound',
  timestamp: '2021-03-29T21:20:05.582Z'
}
---
EVENT:
{
  headers: {},
  from: '447700900000',
  to: '442038297050',
  uuid: '0779a56d002f1c7f47f82ef5fe84ab79',
  conversation_uuid: 'CON-8f5a100c-fbce-4218-8d4b-16341335bcd6',
  status: 'started',
  direction: 'inbound',
  timestamp: '2021-03-29T21:20:05.582Z'
}
---
EVENT:
{
  start_time: null,
  headers: {},
  rate: null,
  from: '447700900000',
  to: '442038297050',
  uuid: '0779a56d002f1c7f47f82ef5fe84ab79',
  conversation_uuid: 'CON-8f5a100c-fbce-4218-8d4b-16341335bcd6',
  status: 'answered',
  direction: 'inbound',
  network: null,
  timestamp: '2021-03-29T21:20:06.182Z'
}
---
EVENT:
{
  from: '447700900000',
  to: 'Alice',
  uuid: '944bf4bf-8dc7-4e23-86b2-2f4234777416',
  conversation_uuid: 'CON-8f5a100c-fbce-4218-8d4b-16341335bcd6',
  status: 'started',
  direction: 'outbound',
  timestamp: '2021-03-29T21:20:13.025Z'
}
---
EVENT:
{
  start_time: null,
  headers: {},
  rate: null,
  from: '447700900000',
  to: 'Alice',
  uuid: '944bf4bf-8dc7-4e23-86b2-2f4234777416',
  conversation_uuid: 'CON-8f5a100c-fbce-4218-8d4b-16341335bcd6',
  status: 'answered',
  direction: 'outbound',
  network: null,
  timestamp: '2021-03-29T21:20:13.025Z'
}
---
EVENT:
{
  headers: {},
  end_time: '2021-03-29T21:20:16.000Z',
  uuid: '944bf4bf-8dc7-4e23-86b2-2f4234777416',
  network: null,
  duration: '5',
  start_time: '2021-03-29T21:20:11.000Z',
  rate: '0.00',
  price: '0',
  from: '447700900000',
  to: 'Alice',
  conversation_uuid: 'CON-8f5a100c-fbce-4218-8d4b-16341335bcd6',
  status: 'completed',
  direction: 'outbound',
  timestamp: '2021-03-29T21:20:17.574Z'
}
---
EVENT:
{
  headers: {},
  end_time: '2021-03-29T21:20:18.000Z',
  uuid: '0779a56d002f1c7f47f82ef5fe84ab79',
  network: 'GB-FIXED',
  duration: '12',
  start_time: '2021-03-29T21:20:06.000Z',
  rate: '0.00720000',
  price: '0.00144000',
  from: ' 447700900000',
  to: '442038297050',
  conversation_uuid: 'CON-8f5a100c-fbce-4218-8d4b-16341335bcd6',
  status: 'completed',
  direction: 'inbound',
  timestamp: '2021-03-29T21:20:17.514Z'
}
---