トラブルシューティング
既知の問題
このセクションでは、Vonage Client SDK を Web アプリケーションに統合する際に発生する可能性のある、プラットフォーム固有、デバイス固有、およびブラウザ固有の既知の問題について、簡潔に概要を説明します。
Client SDK Integration
User Media Devices Not Being Released
Safari において、ピア接続が切断されたにもかかわらず、ユーザーのメディアデバイスが解放されないという問題が確認されました。これにより、予期しない動作やリソースの過剰使用が生じる可能性があります。Vonage Client SDK for Web を使用して Web アプリケーションを実装する際は、この点にご留意ください。
このセクションでは、Vonage Client SDK を Android アプリケーションに組み込む際に発生する可能性のある、プラットフォーム固有およびデバイス固有の既知の問題について、簡潔に概要を説明します。
Voice SDK Integration
Handling isIncomingCallPermitted Exception
もし isIncomingCallPermitted TelecomManagerのこのメソッドを使用する際は、Xiaomiなどの特定のデバイスでは例外がスローされる可能性があることに注意してください。
正常に動作させるためには、このメソッド呼び出しを try-catch ブロックで囲み、例外が発生した場合に備えてデフォルト値を true に設定することをお勧めします。
そうしないと、アプリで着信コールを行う際に問題が発生する可能性があります。実装方法は以下の通りです:
// Get the TelecomManager instance
val telecomManager = context.getSystemService(AppCompatActivity.TELECOM_SERVICE) as TelecomManager
// Check permissions for incoming calls and handle exceptions
val isIncomingCallPermitted = try {
telecomManager.isIncomingCallPermitted(phoneAccountHandle)
} catch (_: Exception) {
// Exception occurred, default to true
true
}
このアプローチを採用することで、アプリケーションは発生しうる例外を適切に処理し、特に `isIncomingCallPermitted` メソッドがエラーをスローする可能性があるデバイスにおいても、機能の中断を防ぐことができます。
ConnectionService Unavailability Workaround
一部のデバイス(例えば、機内モードに設定されたSamsung製スマートフォンなど)では、発信処理に必要なConnectionServiceが利用できない場合があり、問題が発生する可能性があります。 この問題に対処するため、ConnectionServiceが利用できない場合でも通話ができるようにする回避策をご紹介します。
Workaround for Placing Outgoing Calls
ConnectionServiceが利用できない場合、Applicationsで発信を行うには、以下のコードスニペットを使用してください:
// Workaround for placing outgoing calls when ConnectionService is not available
private fun placeOutgoingCall(callId: CallId, callee: String) {
try {
coreContext.telecomHelper.startOutgoingCall(callId, callee)
// If ConnectionService does not respond within 3 seconds,
// we mock an outgoing connection
TimerManager.startTimer(TimerManager.CONNECTION_SERVICE_TIMER, 3000) {
mockOutgoingConnection(callId, callee)
}
} catch (e: Exception) {
abortOutboundCall(callId, e.message)
}
}
/**
* This method will mock `ConnectionService#onCreateOutgoingConnection`,
* allowing outgoing calls without direct interaction with the Telecom framework.
*/
private fun mockOutgoingConnection(callId: CallId, to: String): CallConnection {
showToast(context, "ConnectionService Not Available")
val connection = CallConnection(callId).apply {
setAddress(Uri.parse(to), TelecomManager.PRESENTATION_ALLOWED)
setCallerDisplayName(to, TelecomManager.PRESENTATION_ALLOWED)
setDialing()
}
return connection
}
ConnectionService Implementation
次に、以下の例のように、クラスが必要なConnectionServiceメソッドを実装していることを確認してください:
import android.telecom.Connection
import android.telecom.ConnectionRequest
import android.telecom.PhoneAccountHandle
import android.telecom.ConnectionService
import android.telecom.TelecomManager
// Your class implementing ConnectionService
class YourConnectionService : ConnectionService() {
override fun onCreateOutgoingConnection(
connectionManagerPhoneAccount: PhoneAccountHandle?,
request: ConnectionRequest?
): Connection {
// Cancel the timer set in the workaround
TimerManager.cancelTimer(TimerManager.CONNECTION_SERVICE_TIMER)
// Your implementation of ConnectionService onCreateOutgoingConnection method
// ... (code snippet)
return connection
}
override fun onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?) {
// Cancel the timer set in the workaround
TimerManager.cancelTimer(TimerManager.CONNECTION_SERVICE_TIMER)
// Your implementation of ConnectionService onCreateOutgoingConnectionFailed method
// ... (code snippet)
}
}
TimerManager Utility
について TimerManager この回避策で使用されているのは、コールバック関数に対してタイマーを設定できるカスタムユーティリティクラスに過ぎません。
これにより、指定された時間が経過する前にタイマーがキャンセルされなければ、その関数が確実に実行されるようになります。
object TimerManager {
private val handler: Handler = Handler(Looper.getMainLooper())
private val timerMap: MutableMap<String, Runnable> = mutableMapOf()
const val CONNECTION_SERVICE_TIMER = "ConnectionServiceTimer"
fun startTimer(timerId: String, delayMillis: Long, callback: () -> Unit) {
val runnable = Runnable {
callback.invoke()
timerMap.remove(timerId)
}
timerMap[timerId] = runnable
handler.postDelayed(runnable, delayMillis)
}
fun cancelTimer(timerId: String) {
val runnable = timerMap[timerId]
if (runnable != null) {
handler.removeCallbacks(runnable)
timerMap.remove(timerId)
}
}
}
この回避策とTimerManagerユーティリティを組み込むことで、ConnectionServiceが正常に機能しない可能性のあるデバイスであっても、アプリケーションは発信通話を効果的に管理できるようになります。
このセクションでは、Vonage Client SDK を iOS アプリケーションに組み込む際に発生する可能性のある、プラットフォーム固有およびデバイス固有の既知の問題について、簡潔に概要を説明します。
Voice SDK Integration
Speakerphone Issues
通話中にスピーカーフォンボタンで不具合(クラッシュや反応しないなど)が発生した場合は、
以下の操作が干渉していないことを確認してください。 AVAudioSession.sharedInstance().
Client SDK では、オーディオセッションの処理はすでに自動的に行われているため、 避ける 次のようなコードを使って直接操作する:
AVAudioSession.sharedInstance().setCategory(.playAndRecord)
Client SDKがオーディオセッションの管理をすべて行いますので、ご安心ください。
CallKit を利用しているユーザーについては、引き続き以下の関数を呼び出す必要があります。 VGVoiceClient.enableAudio(audioSession) そして VGVoiceClient.disableAudio(audioSession) CallKitのデリゲートメソッドによって提供されるaudioSessionを使用して。
Vonage CLI を使用する
Vonageアプリケーションのセットアップ
複数のVonageアプリケーションを作成できるため、実行するコマンドは設定したアプリケーションを参照します。例えば、ユーザーを作成する場合、必ず意図したアプリケーション上に作成する必要があります。
- CLIが参照しているアプリを確認してください:
コマンドに反応しない
コマンドを実行しても反応がない:
- コマンドに含まれるJSONオブジェクトがすべてクローズド・オブジェクトであることを確認し、以下のいずれかが欠けていないことを確認する。
}または'例えば
JWT
JWTはVonage Applicationごとにユーザーごとに設定されます。
無効なトークン・エラー
-
を確認してください。
"application_id"の主張は正しい。 -
を確認してください。
"sub"が正しいことを確認してください。つまり、このユーザ名のユーザがVonageアプリケーションに存在します。 -
JWTの有効期限が切れていないことを確認する:
-
有効期限は
"exp"Unix時間で、1970年1月1日(UTC)からの秒数です。 -
あなたは 人間の時間に変換する.
-
有効期限が未来、つまりJWTの有効期限がまだ切れていないことを確認してください。
-
接続エラーまたは接続タイムアウト
SDKにログインしようとすると、接続エラーまたは接続タイムアウトが発生します:
-
デバイスのインターネット接続を確認してください。
-
では
JWTはJWT標準では有効かもしれませんが、Vonageの要件に従っていくつかのクレームを持つことは正しくないかもしれません。新しいJWTVonage特有の主張の正しさを確認しながら。
JWT生成時のエラー
-
秘密鍵ファイルが存在することを確認してください。アプリケーションを作成したマシンで生成されます。
-
私たちのドキュメントでは、CLIを使用する場合、次のパスを使用することを推奨しています。
./private.key. -
JWTを生成するマシンに秘密鍵が存在し、パスが正しいことを確認してください。
-
新しい秘密鍵が必要な場合
-
から入手できる。 ダッシュボード.左側のメニューからVoice → Your Applications → アプリケーションを選択 → Edit.一番下の
Generate public / private key pair.をクリックしてください。Save changes. -
そのファイルをあなたのマシンに保存し、JWTを生成する際にそのファイルへのパスを更新する。
-
プッシュ通知
-
証明書をVonageのサーバーにアップロードしたことを確認してください。有効なadmin JWTが必要です。
subクレームあなたは JWTをデコードする を確認する。 -
プッシュ通知が有効になっていること、およびメソッド
client.registerVoipToken()が成功したことを確認する。呼び出しが成功したことを確認するために、ログ呼び出しやブレークポイントを置くこともできる。
ご質問はこちら
ご不明な点、ご質問、ご意見等ございましたら、下記までご連絡ください。 devrel@vonage.com または Vonage開発者コミュニティSlack.