
AndroidとFlutterを使ってアプリと電話の通話を構築する
所要時間:2 分
今日は、Androidアプリケーションを Flutterを使ってAndroidアプリケーションを構築し、Vonage Client SDKを利用してモバイルアプリケーションから電話に電話をかけます。アプリケーションには3つの画面(3つのUI状態)があります:

前提条件
ソースコードは GitHub.
Androidデバイス用のアプリケーションのビルドを始める前に、以下の前提条件を準備する必要があります:
コール・コントロール・オブジェクト(NCCO)
Vonage CLIをインストールする
Vonageアプリケーションのセットアップ
Flutter SDKをインストールする
Flutterプロジェクトを作成する
Vonageアプリケーション
NCCOの設立
Call Control Object (NCCO) は、Voice APIコールのフローを制御するために使用するJSON配列です。NCCOの詳細については、こちらをご覧ください。 こちら.
NCCOは公開され、インターネットからアクセスできる必要がある。そのために、このチュートリアルでは GitHub Gistを使います。新しいGistを追加しよう:
次のサイトへ https://gist.github.com/(Githubにログインする必要があります)
新しいgistを
ncco.jsonファイル名以下のJSONオブジェクトをコピーしてgistに貼り付ける:
[
{
"action": "talk",
"text": "Please wait while we connect you."
},
{
"action": "connect",
"endpoint": [
{
"type": "phone",
"number": "PHONE_NUMBER"
}
]
}
]置き換える
PHONE_NUMBERを私たちの電話番号に置き換えてください(Vonageの番号はE.164形式です。 https://developer.nexmo.com/concepts/guides/glossary#e-164-formatと「-」は無効です。私たちの電話番号を入力する際、国コードを必ず指定してください:14155550100 および UK:447700900001)をクリックしてください。
Create secret gistボタンをクリックしてください。
Rawボタンブラウザに表示されたURLに注意してください。
Vonage CLIをインストールする
Vonage CLI Vonage CLIを使うと、コマンドラインで多くの操作ができるようになります。アプリケーションの作成やVonage Numbersの購入などのタスクを実行したい場合は、Vonage CLIをインストールする必要があります。
Vonage CLIには node.jsが必要なので、node.jsをインストールする必要があります。 をインストールする必要があります。.
NPMを使ってCLIのベータ版をインストールするには、次のコマンドを実行する:
npm install @vonage/cli -gVonageのAPIキーとAPIシークレットを使うようにvonage CLIを設定します。 設定ページで取得できます。
ターミナルで以下のコマンドを実行し、api_keyとapi_secretを独自のものに置き換える:
vonage config:set --apiKey=api_key --apiSecret=api_secret Vonageアプリケーションのセットアップ
まだプロジェクト・ディレクトリを作成していない場合は、ターミナルで以下のコマンドを実行する:
mkdir vonage-tutorial2.プロジェクトディレクトリに移動する:
cd vonage-tutorial3.以下のコマンドをターミナルにコピー&ペーストしてVonageアプリケーションを作成します。 --voice-answer-url引数の GIST-URLを前のステップのgist URLに置き換えて、引数の値を変更してください。
vonage apps:create "App to Phone Tutorial" --voice_event_url=https://example.com/ --voice_answer_url=GIST-URLアプリケーションの作成時にターミナルに表示されるアプリケーションIDをメモしておくこと。
注:プロジェクトディレクトリに
vonage_app.jsonという名前のファイルがプロジェクトディレクトリに作成され、新しく作成されたVonageアプリケーションIDと秘密鍵が含まれています。という名前の秘密鍵ファイルも作成されます。app_to_phone_tutorial.keyという名前の秘密鍵ファイルも作成されます。
ユーザー作成
各参加者は ユーザーオブジェクトで表され、Client SDKによって認証されなければなりません。本番アプリケーションでは、通常、このユーザー情報をデータベースに保存します。
というユーザーを作成するために、以下のコマンドを実行する。 Alice
vonage apps:users:create Alice JWTの生成
JWTはユーザーの認証に使用される。ターミナルで以下のコマンドを実行し、ユーザーのJWTを生成する。 Alice.
以下のコマンドの APPLICATION_IDをアプリケーションのIDに置き換えてください:
vonage jwt --app_id=APPLICATION_ID --subject=Alice --key_file=./app_to_phone_tutorial.key --acl='{
"paths": {
"/*/users/**": {},
"/*/conversations/**": {},
"/*/sessions/**": {},
"/*/devices/**": {},
"/*/image/**": {},
"/*/media/**": {},
"/*/push/**": {},
"/*/knocking/**": {},
"/*/legs/**": {}
}
}'上のコマンドは、JWTの有効期限を最大で1日後に設定している。
に対して生成したJWTをメモしておいてください。 Alice.
注:本番環境では、アプリケーションは、各クライアントリクエストに対してJWTを生成するエンドポイントを公開する必要があります。
Android Studioをインストールする
ダウンロードとインストール アンドロイドスタジオ.
フラッターセットアップ
Flutter SDKをインストールする
このステップはMacOS、Win、Linuxで異なるが、一般的には、指定したOS用のflutter SDKをダウンロードし、SDKファイルを解凍し、そのフォルダをシステムのPATH変数に追加する。 sdk\binフォルダをシステムのPATH変数に追加します。詳しい手順は こちら.
幸い、flutterにはSDKと必要な "コンポーネント "がすべて存在し、正しく設定されているかどうかを確認できるツールが付属している。以下のコマンドを実行する:
flutter doctorFlutter DoctorはFlutter SDKがインストールされているか、その他のコンポーネントが正しくインストールされ設定されているかをVerifyします。問題が検出された場合、修正に関する説明とヒントが表示されます。
Flutterプラグインをインストールする
開く アンドロイドスタジオにアクセスし Preferences | pluginsにアクセスし、マーケットプレイスからFlutterとDartプラグインをインストールする。
Flutterプラグインは、Flutterアプリケーションの実行とデバッグを可能にする新しいツールバーを追加する:

Flutterプロジェクトを作成する
Android Studioを使ってFlutterプロジェクトを作成します。
Android Studioを実行する
Android Studioのウェルカム画面で
Create New Flutter project

を選択し
Flutter Applicationを選択しNextプロジェクト名
app_to_phone_flutterを入力しFlutter SDK pathを入力しNextを選択し
Include Kotlin support for Android codeを選択しFinish
以下のことに注意してください
app_to_phone_flutterフォルダ(flutterプロジェクト)にはiosOSプロジェクトが含まれるフォルダとiosiOSプロジェクトが入っている
Androidデバイスまたはエミュレータを接続し、アプリを実行して、すべてが期待どおりに動作することを確認します。
FlutterとAndroidの双方向通信
現在、Client SDKはFlutterのパッケージとして提供されていないため、次のものを使用する必要があります。 AndroidネイティブのClient SDKを使い、AndroidとFlutterの間で メソッドチャネル- を使ってAndroidとFlutterの間で通信する必要がある。
Flutterのコードは lib/ain.dartファイルに格納され、Androidネイティブコードは android/app/src/main/kotlin/com/example/app_to_phone_flutter/MainActivity.ktファイルに格納される。
Flutterアプリケーションの初期化
Flutterアプリケーションは、以下のプログラミング言語を使って構築される。 ダート.
ファイルを開き lib/main.dartファイルを開き、すべての内容を以下のコードに置き換える:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: CallWidget(title: 'app-to-phone-flutter'),
);
}
}
class CallWidget extends StatefulWidget {
CallWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_CallWidgetState createState() => _CallWidgetState();
}
class _CallWidgetState extends State<CallWidget> {
SdkState _sdkState = SdkState.LOGGED_OUT;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 64),
_updateView()
],
),
),
);
}
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
child: Text("LOGIN AS ALICE")
);
}
}
Future<void> _loginUser() async {
// Login user
}
Future<void> _makeCall() async {
// Make call
}
Future<void> _endCall() async {
// End call
}
}
enum SdkState {
LOGGED_OUT,
LOGGED_IN,
WAIT,
ON_CALL,
ERROR
}上記のコードには、アプリケーションの状態を管理するカスタム CallWidgetが含まれており、アプリケーションの状態(ユーザーのログ記録と呼び出しの管理)を管理します。この SdkStateenumはVonage Client SDKの可能な状態を表します。このenumは2回定義されます。1回はDartを使ったFlutter用、もう1回はKotlinを使ったAndroid用です。ウィジェットには _updateViewメソッドが含まれています。 SdkState値に基づいてUIを変更するメソッドが含まれています。
Flutterツールバーの緑の矢印ボタンを使ってアプリケーションを実行する:

が表示されるはずです。 Login Aliceボタンをクリックします:

ログイン画面
ボタンが無効になっています。 Login as Aiceボタンは無効になっているので onPressedハンドラを ElevatedButtonを追加します:
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
onPressed: () { _loginUser(); },
child: Text("LOGIN AS ALICE")
);
}
}の本体を更新する。 _loginUserメソッド本体を更新し、ネイティブコードと通信してユーザーにログインする:
Future<void> _loginUser() async {
String token = "ALICE_TOKEN";
try {
await platformMethodChannel.invokeMethod('loginUser', <String, dynamic>{'token': token});
} on PlatformException catch (e) {
print(e);
}
}を ALICE_TOKENを JWT トークンに置き換えてください。 Aliceに置き換える。Flutterは loginUserメソッドを呼び出し、引数として tokenを引数として渡します。引数として loginUserクラスで定義された MainActivityクラスで定義されているメソッドです(すぐにわかります)。Flutterからこのメソッドを呼び出すには MethodChannel.フィールドを追加します。 platformMethodChannelフィールドを _CallWidgetStateクラスの先頭にフィールドを追加します:
class _CallWidgetState extends State<CallWidget> {
SdkState _sdkState = SdkState.LOGGED_OUT;
static const platformMethodChannel = const MethodChannel('com.vonage');この com.vonage文字列はユニークなチャンネルIDを表し、Androidのネイティブ・コード(MainActivityクラス)にも参照される。次に、Androidネイティブ側でこのメソッド呼び出しを処理する必要がある。
オープン MainActivityクラスを開く。Flutterプラグインは、Android Studioの別のインスタンス(別のウィンドウ)でこのAndroidプロジェクトを開くヒントを表示することに注意してください。そうすることで、Androidプロジェクトのコード補完がしやすくなります:

注:これはFlutterプロジェクトがAndroidプロジェクトとiOSプロジェクトで構成されているために起こります。
をオーバーライドして、Flutterから発信されるメソッドコールをリッスンする。 configureFlutterEngineを追加し addFlutterChannelListenerメソッド呼び出しを configureFlutterEngineメソッドに追加します:
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
addFlutterChannelListener()
}を加える。 addFlutterChannelListenerそして loginUserメソッドを MainActivityメソッドを追加します。 configureFlutterEngineメソッドと同じレベル):
private fun addFlutterChannelListener() {
MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"loginUser" -> {
val token = requireNotNull(call.argument<String>("token"))
loginUser(token)
result.success("")
}
else -> {
result.notImplemented()
}
}
}
}
private fun loginUser(token: String) {
Log.d("TAG", "login with token: $token")
}アプリケーションを実行すると login with token...メッセージが表示されます。では、次に client.
Client SDKの依存関係の追加
カスタムMaven URLリポジトリをGradle設定に追加します。プロジェクトレベルの allprojectsブロック内に以下のmavenブロックを追加します。 build.gradle.ktsファイル内に以下のmavenブロックを追加します:
allprojects {
repositories {
google()
jcenter()
maven {
url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local"
}
}
}Client SDKの依存関係をプロジェクトに追加します。 app\build.gradleファイルに追加します:
dependencies {
// ...
implementation 'com.nexmo.android:client-sdk:2.8.1'
}同じファイルで、min Android SDKのバージョンを次のように設定する。 23:
minSdkVersion 23実行 Sync project with Gradleコマンドを実行します:

クライアントの初期化
開く MainActivityクラスを開き clientプロパティを追加します:
private lateinit var client: NexmoClient次に initClientメソッドを追加する:
private fun initClient() {
client = NexmoClient.Builder().build(this)
}既存の initClientメソッドを呼び出すには configureFlutterEngineメソッドを呼び出すには、以下の例のように initClient()行を追加する必要がある:
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
initClient()
addFlutterChannelListener()
} ログイン ユーザー
メソッド本体を修正する loginメソッド本体を修正して loginを呼び出すように修正する:
private fun login(token: String) {
client.login(token)
}これにより、クライアントSDKを使用してユーザー(Alice) を Client SDK を使用してログインすることができます。
Client SDKの状態変更をFlutterに通知する
SDKのステートの変更をFlutterに通知するには、クライアントSDKのステートを表すために enumを追加する必要があります。同等の SdkState列挙型を main.dartファイルに追加済みです)。次のSdkStateenumを追加します。 MainActivity.ktファイルの一番下に
enum class SdkState {
LOGGED_OUT,
LOGGED_IN,
WAIT,
ON_CALL,
ERROR
}次に、接続リスナーを追加し、SDKステートのいくつかを SdkStateenumにマッピングする必要があります。以下の例のように initClientメソッドの本体を修正します:
private fun initClient() {
client = NexmoClient.Builder().build(this)
client.setConnectionListener { connectionStatus, _ ->
when (connectionStatus) {
ConnectionStatus.CONNECTED -> notifyFlutter(SdkState.LOGGED_IN)
ConnectionStatus.DISCONNECTED -> notifyFlutter(SdkState.LOGGED_OUT)
ConnectionStatus.CONNECTING -> notifyFlutter(SdkState.WAIT)
ConnectionStatus.UNKNOWN -> notifyFlutter(SdkState.ERROR)
}
}
}最後に notifyFlutterメソッドを MainActivityクラスに追加する必要がある:
private fun notifyFlutter(state: SdkState) {
Handler(Looper.getMainLooper()).post {
MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, "com.vonage")
.invokeMethod("updateState", state.toString())
}
}enumに状態を保存しているが、文字列として送信していることに注目してほしい。Flutterとの通信は mainスレッド上で起こるので Handlerを使ってスレッドを切り替える必要がある。そのため MethodChannelは updateStateメソッドを呼び出します。 main.dartファイルで定義されているメソッドを呼び出す。
FlutterによるSDK状態の取得
Flutterでステートの更新を取得するには、メソッドチャンネルの更新をリッスンする必要がある。ファイルを開き main.dartファイルを開き、以下の2つのメソッドを _CallWidgetStateクラスに追加する:
_CallWidgetState() {
platformMethodChannel.setMethodCallHandler(methodCallHandler);
}
Future<dynamic> methodCallHandler(MethodCall methodCall) async {
switch (methodCall.method) {
case 'updateState':
{
setState(() {
var arguments = 'SdkState.${methodCall.arguments}';
_sdkState = SdkState.values.firstWhere((v) {return v.toString() == arguments;}
);
});
}
break;
default:
throw MissingPluginException('notImplemented');
}
}これらのメソッドは、Androidから "シグナル "を受け取り、それをenumに変換する。ここで _updateViewメソッドの内容を更新して SdkState.WAITそして SdkState.LOGGED_INの状態に更新する:
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
onPressed: () { _loginUser(); },
child: Text("LOGIN AS ALICE")
);
} else if (_sdkState == SdkState.WAIT) {
return Center(
child: CircularProgressIndicator(),
);
} else if (_sdkState == SdkState.LOGGED_IN) {
return ElevatedButton(
onPressed: () { _makeCall(); },
child: Text("MAKE PHONE CALL")
);
}
}期間中 SdkState.WAITプログレスバーが表示されます。ログインに成功すると MAKE PHONE CALLボタンが表示されます。
注意:Androidのネイティブコードを修正する際、Flutterのホットリロードは機能しない。
アプリを起動し LOGIN AS ALICE.ボタンをクリックする。 MAKE PHONE CALLボタンが表示されるはずです。 SdkStateenum`)に基づいたFlutterアプリの別の状態です。この例を下の画像に示す:

電話をかける
次に、電話をかける機能を追加する必要がある。ファイルを開き main.dartファイルを開き _makeCallメソッドのボディを更新します:
Future<void> _makeCall() async {
try {
await requestPermissions();
await platformMethodChannel
.invokeMethod('makeCall');
} on PlatformException catch (e) {
print(e);
}
}上記のメソッドはアンドロイドと通信する。 MainActivityクラスのコードも更新しなければならない。追加 makeCall節を when文に節を追加する。 addFlutterChannelListenerメソッドに節を追加する:
private fun addFlutterChannelListener() {
MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, "com.vonage").setMethodCallHandler { call, result ->
when (call.method) {
"loginUser" -> {
val token = requireNotNull(call.argument<String>("token"))
login(token)
result.success("")
}
"makeCall" -> {
makeCall()
result.success("")
}
else -> {
result.notImplemented()
}
}
}
}次に同じファイルに onGoingCallプロパティを追加する:
private var onGoingCall: NexmoCall? = null注意:現在、Client SDKは進行中のコール参照を保存しません。
MainActivityクラスに格納する必要があります。
同じファイルに makeCallメソッドを追加します:
@SuppressLint("MissingPermission")
private fun makeCall() {
notifyFlutter(SdkState.WAIT)
// Callee number is ignored because it is specified in NCCO config
client.call("IGNORED_NUMBER", NexmoCallHandler.SERVER, object : NexmoRequestListener<NexmoCall> {
override fun onSuccess(call: NexmoCall?) {
onGoingCall = call
notifyFlutter(SdkState.ON_CALL)
}
override fun onError(apiError: NexmoApiError) {
notifyFlutter(SdkState.ERROR)
}
})
}上記のメソッドはFlutterアプリの状態を SdkState.WAITに設定し、Client SDKのレスポンス(エラーまたは成功)を待ちます。ここで両方の状態 (SdkState.ON_CALLと SdkState.ERRORの両方のサポートを main.dartファイル(Flutter)内に追加する必要があります。以下のように _updateViewメソッドのボディを以下のように更新する:
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
onPressed: () { _loginUser(); },
child: Text("LOGIN AS ALICE")
);
} else if (_sdkState == SdkState.WAIT) {
return Center(
child: CircularProgressIndicator(),
);
} else if (_sdkState == SdkState.LOGGED_IN) {
return ElevatedButton(
onPressed: () { _makeCall(); },
child: Text("MAKE PHONE CALL")
);
} else if (_sdkState == SdkState.ON_CALL) {
return ElevatedButton(
onPressed: () { _endCall(); },
child: Text("END CALL")
);
} else {
return Center(
child: Text("ERROR")
);
}
}状態が変わるたびに、UIが変更される。通話を行う前に、アプリケーションはマイクを使用するための特定のパーミッションが必要です。次のステップでは、これらの許可を要求する機能をプロジェクトに追加します。
リクエスト許可
アプリケーションはマイクにアクセスできる必要があるので、Androidの android.permission.RECORD_AUDIOパーミッション(Flutterでは Permission.microphone).
まず パッケージパッケージを追加する必要がある。ファイルを開き pubspec.yamlファイルを開き permission_handler: ^6.0.1+1依存関係を sdk: flutter:
dependencies:
flutter:
sdk: flutter
permission_handler: ^6.0.1+1ファイルではインデントが重要です。
yamlファイルではインデントが重要なのでpermission_handlerと同じインデント・レベルであることを確認してください。flutter:項目と同じインデントレベルであることを確認してください。
ターミナルで以下のコマンドを実行し、新しく追加されたFlutterパッケージをダウンロードする:
flutter pub getファイルの先頭で main.dartファイルの先頭に permission_handlerパッケージをインポートする必要があります:
import 'package:permission_handler/permission_handler.dart';特定のパーミッションのリクエストをトリガーするには requestPermissions()メソッドを _CallWidgetStateクラス内のメソッドを main.dartファイルに追加する必要があります。そこで、この新しいメソッドをクラス内に追加します:
Future<void> requestPermissions() async {
await [ Permission.microphone].request();
}最後に、2つのパーミッション(uses-permissionタグ)を app/src/main/AndroidManifest.xmlファイル内の applicationタグの上に
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
...注意:
android.permission.INTERNETパーミッションはAndroidによって暗黙的に付与されるので、Flutterで明示的にリクエストする必要はない。
アプリを起動し MAKE PHONE CALLをクリックして通話を開始します。許可ダイアログが表示され、許可を与えると通話が開始されます。
備考:NCCOで電話番号を定義しました。
アプリケーションの状態は SdkState.ON_CALLに更新され、UIが更新されます:

通話を終了する
呼び出しを終了するには、ネイティブのAndroidアプリケーション上でメソッドをトリガーする必要がある。 platformMethodChannel.内部 main.dartファイル更新の _endCallメソッドの内部で
Future<void> _endCall() async {
try {
await platformMethodChannel.invokeMethod('endCall');
} on PlatformException catch (e) {}
}上記のメソッドはアンドロイドと通信するため、次のようにコードを更新しなければならない。 MainActivityクラスのコードを更新する必要があります。追加 endCall節を when文に節を追加する。 addFlutterChannelListenerメソッド内に追加します:
when (call.method) {
"loginUser" -> {
val token = requireNotNull(call.argument<String>("token"))
login(token)
result.success("")
}
"makeCall" -> {
makeCall()
result.success("")
}
"endCall" -> {
endCall()
result.success("")
}
else -> {
result.notImplemented()
}
}同じファイルに endCallメソッドを追加する:
private fun endCall() {
onGoingCall?.hangup(object : NexmoRequestListener<NexmoCall> {
override fun onSuccess(call: NexmoCall?) {
onGoingCall = null
notifyFlutter(SdkState.LOGGED_IN)
}
override fun onError(apiError: NexmoApiError) {
notifyFlutter(SdkState.ERROR)
}
})
}上記のメソッドはFlutterアプリの状態を SdkState.WAITに設定し、Client SDKからのレスポンスを待つ。どちらのUI状態もFlutterアプリケーションですでにサポートされている。
FlutterアプリのUIで END CALLボタンを押すことで通話を終了させましたが、通話はFlutterアプリの外でも終了させることができます。
これらのケースをサポートするには、コール・インスタンスに NexmoCallEventListenerリスナーをコールインスタンスに追加し、コール固有のイベントをリッスンする必要がある。
を定義する。 callEventListenerプロパティを MainActivityクラスのトップに定義します:
private val callEventListener = object : NexmoCallEventListener {
override fun onMemberStatusUpdated(callMemberStatus: NexmoCallMemberStatus, callMember: NexmoCallMember) {
if (callMemberStatus == NexmoCallMemberStatus.COMPLETED || callMemberStatus == NexmoCallMemberStatus.CANCELLED) {
onGoingCall = null
}
}
override fun onMuteChanged(mediaActionState: NexmoMediaActionState, callMember: NexmoCallMember) {}
override fun onEarmuffChanged(mediaActionState: NexmoMediaActionState, callMember: NexmoCallMember) {}
override fun onDTMF(dtmf: String, callMember: NexmoCallMember) {}
}コールバックは onMemberStatusUpdatedコールバックは、通話が終了したことを知らせる。
上記のリスナーを登録するには onSuccessコールバック makeCallメソッドの中で
onGoingCall = call
onGoingCall?.addCallEventListener(callEventListener)最後に endCallメソッドを修正して callEventListenerメソッドを修正します。 onSuccessコールバックの
onGoingCall?.removeCallEventListener(callEventListener)
onGoingCall = nullアプリを起動し、このチュートリアルのステップに従えば、モバイルアプリから物理的な電話番号に電話をかけることができます。
概要
アプリケーションのビルドに成功しました。これにより、Vonage Client SDKを使用してモバイルアプリケーションから電話に電話をかける方法を学びました。完全版は GitHub.
他のユースケースに慣れるには、以下をご覧ください。 他のチュートリアルおよび Vonage 開発者センター.