
Construire un appel App-To-Phone en utilisant Android et Flutter
Temps de lecture : 12 minutes
Aujourd'hui, nous allons construire une application Android à l'aide de Flutter et utiliser Vonage Client SDK pour passer un appel depuis une application mobile vers le téléphone. L'application aura 3 écrans (3 états de l'interface utilisateur) :

Conditions préalables
Le code source est disponible sur GitHub.
Avant de commencer à construire l'application pour notre appareil Android, vous devrez vous préparer avec les prérequis suivants :
Créer un objet de contrôle d'appel (NCCO)
Installer le CLI de Vonage
Mise en place d'une application Vonage
Installer le SDK Flutter
Créer un projet Flutter
Applications Vonage
Créer un OCNI
Un objet de contrôle d'appel (NCCO) est un tableau JSON que nous utilisons pour contrôler le flux d'un appel Voice API. Vous trouverez plus d'informations sur le NCCO ici ici.
Le NCCO doit être public et accessible par l'internet. Pour ce faire, vous utiliserez dans ce tutoriel la GitHub Gist qui offre un moyen pratique d'héberger la configuration. Ajoutons une nouvelle gist :
Aller à https://gist.github.com/ (vous devez être connecté à Github)
Créer un nouveau gist avec
ncco.jsonle nom du fichierCopiez et collez l'objet JSON suivant dans le gist :
[
{
"action": "talk",
"text": "Please wait while we connect you."
},
{
"action": "connect",
"endpoint": [
{
"type": "phone",
"number": "PHONE_NUMBER"
}
]
}
]Remplacer
PHONE_NUMBERpar notre numéro de téléphone (les numéros de Vonage sont au format E.164 https://developer.nexmo.com/concepts/guides/glossary#e-164-formatLes lettres "+" et "-" ne sont pas valables. Veillez à préciser l'indicatif de notre pays lors de la saisie de notre numéro, par exemple, US : 14155550100 et UK : 447700900001)Cliquez sur le bouton
Create secret gistboutonCliquez sur le bouton
RawboutonPrenez note de l'URL affichée dans notre navigateur, nous l'utiliserons dans l'étape suivante.
Installer le CLI de Vonage
L'interface CLI de Vonage CLI de Vonage nous permet d'effectuer de nombreuses opérations sur la ligne de commande. Si nous voulons effectuer des tâches telles que la création d'applications, l'achat de numéros Vonage, etc., nous devons installer le CLI de Vonage.
L'interface de programmation de Vonage nécessite node.jsNous devons donc commencer par installer node.js en suivant les instructions suivantes ces instructions.
Pour installer la version Beta du CLI avec NPM, exécutez cette commande :
npm install @vonage/cli -gConfigurer le CLI de Vonage pour utiliser notre clé API et notre secret API de Vonage. page des paramètres dans le tableau de bord.
Exécutez la commande suivante dans un terminal, en remplaçant api_key et api_secret par les nôtres :
vonage config:set --apiKey=api_key --apiSecret=api_secret Configuration de l'application Vonage
Créez notre répertoire de projet si vous ne l'avez pas encore fait, exécutez la commande suivante dans votre terminal :
mkdir vonage-tutorial2. Entrez dans le répertoire du projet :
cd vonage-tutorial3. Créez une application Vonage en copiant et en collant la commande ci-dessous dans le terminal. --voice-answer-url en remplaçant GIST-URL par l'URL gist de l'étape précédente.
vonage apps:create "App to Phone Tutorial" --voice_event_url=https://example.com/ --voice_answer_url=GIST-URLNotez l'identifiant de l'Application qui est affiché dans notre terminal lors de la création de notre application.
NOTE : Un fichier nommé
vonage_app.jsonest créé dans le répertoire de notre projet et contient l'identifiant de l'application Vonage nouvellement créée et la clé privée. Un fichier de clé privée nomméapp_to_phone_tutorial.keyest également créé.
Créer un utilisateur
Chaque participant est représenté par un utilisateur et doit être authentifié par le Client SDK. Dans une application de production, nous stockons généralement ces informations sur l'utilisateur dans une base de données.
Exécutez la commande suivante pour créer un utilisateur appelé Alice
vonage apps:users:create Alice Générer un JWT
Le JWT est utilisé pour authentifier l'utilisateur. Exécutez la commande suivante dans le terminal pour générer un JWT pour l'utilisateur Alice.
Dans la commande suivante, remplacez le APPLICATION_ID par l'ID de notre application :
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/**": {}
}
}'La commande ci-dessus fixe l'expiration du JWT à un jour à partir de maintenant, ce qui est le maximum.
Notez le JWT que nous avons généré pour Alice.
NOTE : Dans un environnement de production, notre application devrait exposer un point de terminaison qui génère un JWT pour chaque demande du client.
Installer Android Studio
Télécharger et installer Android Studio.
Mise en place de Flutter
Installer le SDK Flutter
Cette étape varie selon qu'il s'agit de MacOS, Win ou Linux, mais en général, elle se résume à télécharger le SDK Flutter pour un système d'exploitation donné, à extraire le fichier SDK et à ajouter le dossier sdk\bin à la variable PATH du système. Des instructions détaillées peuvent être trouvées ici.
Heureusement, flutter est livré avec un outil qui nous permet de vérifier si le SDK et tous les "composants" requis sont présents et configurés correctement. Exécutez cette commande :
flutter doctorFlutter Doctor vérifiera si Flutter SDK est installé et si les autres composants sont installés et configurés correctement. Si des problèmes sont détectés, nous verrons la description et les conseils concernant la correction.
Installer le plugin Flutter
Ouvrir Android StudioAllez sur Preferences | plugins et installez les plugins Flutter et Dart depuis la place de marché.
Le plugin Flutter ajoutera une nouvelle barre d'outils qui permet d'exécuter et de déboguer l'application Flutter :

Créer le projet Flutter
Vous allez créer un projet Flutter à l'aide d'Android Studio.
Exécuter Android Studio
Dans l'écran d'accueil d'Android Studio, sélectionnez
Create New Flutter project

Sélectionnez
Flutter Applicationet cliquez surNextSaisir
app_to_phone_fluttercomme nom de projet, entrezFlutter SDK pathet cliquez surNextSélectionnez
Include Kotlin support for Android codeet cliquez surFinish
Remarquez que
app_to_phone_flutter(projet flutter) contientiosun dossier contenant le projet OS etiosle dossier contenant le projet iOS.
Connectez l'appareil Android ou l'émulateur et exécutez l'application pour vérifier que tout fonctionne comme prévu.
Communication bidirectionnelle Flutter/Android
Actuellement, Client SDK n'est pas disponible en tant que package Flutter, nous devrons donc utiliser Client SDK natif d'Android et communiquer entre Android et Flutter à l'aide de CanalMéthode - de cette façon, Flutter appellera les méthodes Android, et Android appellera les méthodes Flutter.
Le code Flutter sera stocké dans le fichier lib/ain.dart tandis que le code natif d'Android sera stocké dans le fichier android/app/src/main/kotlin/com/example/app_to_phone_flutter/MainActivity.kt fichier.
Init Flutter Application
Les applications Flutter sont construites à l'aide d'un langage de programmation appelé Dart.
Ouvrir lib/main.dart et remplacez tout le contenu par le code suivant :
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
}Le code ci-dessus contient le code personnalisé CallWidget qui sera responsable de la gestion de l'état de l'application (enregistrement de l'utilisateur et gestion de l'appel). L'énumération SdkState représente les états possibles de Vonage Client SDK. Cette énumération sera définie deux fois - une pour Flutter en utilisant Dart et une pour Android en utilisant Kotlin. Le widget contient la méthode _updateView qui modifiera l'interface utilisateur en fonction de la valeur de SdkState la valeur.
Exécutez l'application en utilisant le bouton de la flèche verte dans la barre d'outils de Flutter :

Nous devrions voir le Login Alice bouton :

Écran de connexion
Le bouton Login as Aice est désactivé, il faut donc maintenant ajouter onPressed à l'élément ElevatedButton pour permettre l'ouverture d'une session :
Widget _updateView() {
if (_sdkState == SdkState.LOGGED_OUT) {
return ElevatedButton(
onPressed: () { _loginUser(); },
child: Text("LOGIN AS ALICE")
);
}
}Mise à jour du corps de _loginUser pour communiquer avec le code natif et connecter l'utilisateur :
Future<void> _loginUser() async {
String token = "ALICE_TOKEN";
try {
await platformMethodChannel.invokeMethod('loginUser', <String, dynamic>{'token': token});
} on PlatformException catch (e) {
print(e);
}
}Remplacer le ALICE_TOKEN par le jeton JWT, que nous avons obtenu précédemment, pour authentifier l'utilisateur Alice à partir de la CLI de Vonage. Flutter appellera la méthode loginUser et transmettra la méthode token comme argument. La méthode loginUser est définie dans la classe MainActivity (nous y reviendrons dans un instant). Pour appeler cette méthode depuis Flutter, nous devons définir une méthode MethodChannel. Ajouter le champ platformMethodChannel en haut de _CallWidgetState classe :
class _CallWidgetState extends State<CallWidget> {
SdkState _sdkState = SdkState.LOGGED_OUT;
static const platformMethodChannel = const MethodChannel('com.vonage');La chaîne com.vonage représente l'identifiant unique du canal, qui sera également mentionné dans le code natif d'Android (MainActivity ). Nous devons maintenant gérer cet appel de méthode du côté natif d'Android.
Ouvrir MainActivity classe. Notez que le plugin Flutter affiche une astuce pour ouvrir ce projet Android dans une instance séparée d'Android Studio (une autre fenêtre). Faites-le pour obtenir une meilleure complétion de code pour le projet Android :

NOTE : Ceci est dû au fait que le projet Flutter est composé d'un projet Android et d'un projet iOS.
Pour écouter les appels de méthode provenant de Flutter, remplacez configureFlutterEngine et ajouter addFlutterChannelListener à l'intérieur de configureFlutterEngine méthode :
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
addFlutterChannelListener()
}Ajoutez maintenant addFlutterChannelListener et loginUser à l'intérieur de la classe MainActivity (au même niveau que la méthode configureFlutterEngine ci-dessus) :
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")
}Après l'exécution de l'application, nous devrions voir login with token... dans Android Logcat. Il est maintenant temps de créer un fichier manquant client.
Ajouter une dépendance au Client SDK
Ajouter un dépôt d'URL Maven personnalisé à notre configuration Gradle. Ajouter le bloc Maven suivant à l'intérieur du bloc allprojects dans le fichier de niveau projet build.gradle.kts au niveau du projet :
allprojects {
repositories {
google()
jcenter()
maven {
url "https://artifactory.ess-dev.com/artifactory/gradle-dev-local"
}
}
}Ajoutez maintenant la dépendance Client SDK au projet dans le fichier app\build.gradle dans le fichier
dependencies {
// ...
implementation 'com.nexmo.android:client-sdk:2.8.1'
}Dans le même fichier, définissez min Android SDK version to 23:
minSdkVersion 23Exécuter Sync project with Gradle dans Android Studio, comme le montre l'exemple ci-dessous :

Initialiser le client
Ouvrir MainActivity et ajoutez la propriété client qui contiendra la référence au client Nexmo :
private lateinit var client: NexmoClientAjoutez maintenant la méthode initClient pour initialiser le client :
private fun initClient() {
client = NexmoClient.Builder().build(this)
}Pour appeler la méthode initClient à partir de la méthode existante the configureFlutterEngine existante, nous allons devoir ajouter la ligne initClient() comme le montre l'exemple ci-dessous :
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
initClient()
addFlutterChannelListener()
} Connexion de l'utilisateur
Modifier login le corps de la méthode pour appeler login sur l'instance du client :
private fun login(token: String) {
client.login(token)
}Cela nous permettra de connecter l'utilisateur (Alice) à l'aide du Client SDK.
Notifier à Flutter le changement d'état du Client SDK
Pour notifier Flutter de tout changement d'état dans le SDK, vous devrez ajouter enum pour représenter les états du Client SDK. Vous avez déjà ajouté l'équivalent SdkState équivalent dans le fichier main.dart ). Ajoutez l'enum suivantSdkState suivante, au bas du fichier MainActivity.kt au bas du fichier :
enum class SdkState {
LOGGED_OUT,
LOGGED_IN,
WAIT,
ON_CALL,
ERROR
}Ensuite, nous devons ajouter l'écouteur de connexion et faire correspondre certains états du SDK à l'élément SdkState enum. Modifiez le corps de la méthode initClient comme indiqué dans l'exemple ci-dessous :
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)
}
}
}Enfin, la méthode notifyFlutter doit être ajoutée à la MainActivity classe :
private fun notifyFlutter(state: SdkState) {
Handler(Looper.getMainLooper()).post {
MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, "com.vonage")
.invokeMethod("updateState", state.toString())
}
}Remarquez que nous stockons l'état dans l'enum, mais que nous l'envoyons sous la forme d'une chaîne de caractères. La communication avec Flutter se fait sur le thread main nous devons donc utiliser Handler pour changer de thread. La fonction MethodChannel appellera updateState définie dans le fichier main.dart fichier.
Récupérer l'état du SDK par Flutter
Pour récupérer les mises à jour de l'état dans Flutter, nous devons écouter les mises à jour du canal de la méthode. Ouvrez le fichier main.dart et ajoutez ces deux méthodes à l'intérieur de _CallWidgetState classe :
_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');
}
}Ces méthodes reçoivent le "signal" d'Android et le convertissent en une énumération. Mettez maintenant à jour le contenu de la méthode _updateView pour prendre en charge SdkState.WAIT et SdkState.LOGGED_IN comme le montre l'exemple ci-dessous :
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")
);
}
}Pendant la durée de l'opération, la barre de progression s'affiche. SdkState.WAIT la barre de progression s'affiche. Une fois la connexion réussie, l'application affichera le bouton MAKE PHONE CALL s'affichera.
NOTE : Lors de la modification du code natif Android, le rechargement à chaud de Flutter ne fonctionnera pas. nous devons arrêter l'application et l'exécuter à nouveau.
Lancez l'application et cliquez sur le bouton intitulé LOGIN AS ALICE. Le bouton MAKE PHONE CALL devrait apparaître, ce qui représente un autre état de l'application Flutter basé sur l'élément SdkState enum`). Un exemple de ceci est montré dans l'image ci-dessous :

Passer un appel
Nous devons maintenant ajouter la fonctionnalité permettant de passer un appel téléphonique. Ouvrez le fichier main.dart et mettez à jour le corps de la méthode _makeCall comme indiqué ci-dessous :
Future<void> _makeCall() async {
try {
await requestPermissions();
await platformMethodChannel
.invokeMethod('makeCall');
} on PlatformException catch (e) {
print(e);
}
}La méthode ci-dessus communiquera avec Android, nous devons donc mettre à jour le code dans la classe MainActivity également. Ajouter makeCall à la clause when à l'intérieur de la méthode addFlutterChannelListener à l'intérieur de la méthode :
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()
}
}
}
}Maintenant, dans le même fichier, ajoutez la propriété onGoingCall qui définit si et quand un appel est en cours :
private var onGoingCall: NexmoCall? = nullREMARQUE : Actuellement, le Client SDK ne stocke pas la référence de l'appel en cours, nous devons donc la stocker dans la classe
MainActivityNous l'utiliserons plus tard pour mettre fin à l'appel.
Maintenant, dans le même fichier, ajoutez makeCall méthode :
@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)
}
})
}La méthode ci-dessus définit l'état de l'application Flutter à SdkState.WAIT et attend la réponse du Client SDK (erreur ou succès). Nous devons maintenant ajouter le support des deux états (SdkState.ON_CALL et SdkState.ERROR) à l'intérieur du fichier main.dart (Flutter). Mettez à jour le corps de la méthode _updateView pour qu'il soit identique à celui présenté ci-dessous :
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")
);
}
}Chaque changement d'état entraîne une modification de l'interface utilisateur. Avant de passer un appel, l'application a besoin de permissions spécifiques pour utiliser le microphone. Dans l'étape suivante, nous allons ajouter la fonctionnalité dans notre projet pour demander ces permissions.
Demander des autorisations
L'application doit pouvoir accéder au microphone, nous devons donc demander l'autorisation d'Android. android.permission.RECORD_AUDIO d'Android (Flutter l'appelle Permission.microphone).
Tout d'abord, nous devons ajouter l'élément permission_handler . Ouvrez le fichier pubspec.yaml et ajoutez la dépendance permission_handler: ^6.0.1+1 la dépendance sous sdk: flutter:
dependencies:
flutter:
sdk: flutter
permission_handler: ^6.0.1+1L'indentation est importante dans les fichiers
yamlassurez-vous donc que le niveau d'indentation depermission_handlersoit au même niveau d'indentation que l'élémentflutter:.
Exécutez la commande ci-dessous dans le terminal pour télécharger le nouveau paquet Flutter :
flutter pub getEn haut du fichier main.dart vous devez importer le paquetage permission_handler comme indiqué dans l'exemple ci-dessous :
import 'package:permission_handler/permission_handler.dart';Pour déclencher la demande de certaines autorisations, vous devez ajouter la méthode requestPermissions() dans la classe _CallWidgetState dans le fichier main.dart à l'intérieur de la classe. Ajoutez donc cette nouvelle méthode à l'intérieur de la classe :
Future<void> requestPermissions() async {
await [ Permission.microphone].request();
}Enfin, nous devons ajouter deux autorisations (uses-permission ) dans le fichier app/src/main/AndroidManifest.xml au-dessus de la balise application au-dessus de la balise
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
...NOTE :
android.permission.INTERNETLa permission est accordée implicitement par Android, nous n'avons donc pas besoin de la demander explicitement dans Flutter.
Lancez l'application et cliquez sur MAKE PHONE CALL pour démarrer un appel. La boîte de dialogue des autorisations s'affiche et, après avoir accordé les autorisations, l'appel démarre.
Reste : nous avons défini le numéro de téléphone plus tôt dans le NCCO
L'état de l'application sera mis à jour à SdkState.ON_CALL et l'interface utilisateur sera mise à jour :

Fin de l'appel
Pour terminer l'appel, nous devons déclencher la méthode sur l'application native Android à l'aide de la commande platformMethodChannel. Inside main.dart le corps de la méthode _endCall dans le fichier :
Future<void> _endCall() async {
try {
await platformMethodChannel.invokeMethod('endCall');
} on PlatformException catch (e) {}
}La méthode ci-dessus communiquera avec Android, nous devons donc mettre à jour le code dans la classe MainActivity classe. Ajouter endCall à l'instruction when à l'intérieur de la méthode addFlutterChannelListener à l'intérieur de la méthode
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()
}
}Maintenant, dans le même fichier, ajoutez la méthode endCall méthode :
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)
}
})
}La méthode ci-dessus définit l'état de l'application Flutter à SdkState.WAIT et attend la réponse du Client SDK, qui peut être une erreur ou un succès. Les deux états de l'interface utilisateur sont déjà pris en charge dans l'application Flutter.
Vous avez géré la fin de l'appel en appuyant sur le bouton END CALL dans l'interface utilisateur de l'application Flutter, mais l'appel peut également se terminer en dehors de l'application Flutter, par exemple en rejetant l'appel ou en y répondant et en y mettant fin ultérieurement par l'appelant (sur le vrai téléphone).
Pour prendre en charge ces cas, nous devons ajouter un NexmoCallEventListener à l'instance d'appel et écouter les événements spécifiques à l'appel.
Définir la propriété callEventListener en haut de la classe MainActivity classe :
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) {}
}Le onMemberStatusUpdated Le callback nous informe que l'appel est terminé.
Pour enregistrer l'écouteur ci-dessus, modifiez onSuccess le callback à l'intérieur de makeCall la méthode :
onGoingCall = call
onGoingCall?.addCallEventListener(callEventListener)Enfin, modifiez la méthode endCall pour désenregistrer l'écouteur callEventListener à l'intérieur de onSuccess callback :
onGoingCall?.removeCallEventListener(callEventListener)
onGoingCall = nullLancez l'application et si vous avez suivi ce tutoriel étape par étape, vous pourrez passer un appel téléphonique depuis notre application mobile vers un numéro de téléphone physique.
Résumé
Vous avez réussi à construire l'application. Ce faisant, nous avons appris à passer un appel téléphonique à partir d'une application mobile vers le téléphone à l'aide de Vonage Client SDK. Pour la version complète, veuillez consulter ce projet sur GitHub.
Pour vous familiariser avec d'autres cas d'utilisation, veuillez consulter d'autres tutoriels et Centre de développement de Vonage.