如何在Flutter应用中集成Twilio语音通话?求技术协助
Flutter集成Twilio语音通话完整实现步骤
你之前使用的都是Firebase相关依赖,缺少Twilio语音通话的核心包,下面是结合你现有Firebase环境的完整集成方案:
一、添加必要依赖
在pubspec.yaml中加入Twilio语音包,保留你已有的Firebase依赖:
dependencies: flutter: sdk: flutter twilio_programmable_voice: ^0.14.0 # 建议使用最新稳定版本 firebase_core: ^1.18.0 firebase_messaging: ^11.4.2 cloud_functions: ^3.2.17 firebase_auth: ^3.3.20 permission_handler: ^10.2.0 # 用于请求麦克风权限
执行flutter pub get安装依赖。
二、原生平台权限配置
Android端配置
- 在
android/app/src/main/AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- 在
<application>标签内添加Twilio服务:
<service android:name="com.twilio.voice.VoiceService" android:exported="false" />
iOS端配置
- 在
ios/Runner/Info.plist中添加权限描述和后台模式:
<key>NSMicrophoneUsageDescription</key> <string>需要麦克风权限进行语音通话</string> <key>UIBackgroundModes</key> <array> <string>voip</string> </array>
- 打开Xcode,进入Runner项目的
Signing & Capabilities页面,添加Background Modes并勾选Voice over IP选项。
三、通过Firebase云函数生成Twilio Token
Twilio语音通话需要Access Token鉴权,用你已有的Cloud Functions实现Token生成:
- 在Firebase云函数中创建Node.js函数:
const functions = require("firebase-functions"); const twilio = require("twilio"); // 从Firebase环境变量读取Twilio配置(需要先在Firebase控制台配置) const accountSid = functions.config().twilio.account_sid; const authToken = functions.config().twilio.auth_token; const apiKey = functions.config().twilio.api_key; const apiSecret = functions.config().twilio.api_secret; const outgoingAppSid = functions.config().twilio.outgoing_app_sid; const twilioClient = twilio(apiKey, apiSecret, { accountSid }); exports.getTwilioToken = functions.https.onCall(async (data, context) => { // 验证用户已登录 if (!context.auth) { throw new functions.https.HttpsError("unauthenticated", "请先登录"); } // 用用户UID作为Twilio身份标识 const identity = context.auth.uid; // 生成Token const token = twilioClient.jwt.accessToken.create({ identity, ttl: 3600, grants: [ new twilioClient.jwt.accessToken.VoiceGrant({ outgoingApplicationSid: outgoingAppSid, incomingAllow: true, // 允许接收来电 }), ], }); return { token: token.toJwt() }; });
- 部署该函数到Firebase:执行
firebase deploy --only functions
四、Flutter端核心逻辑实现
创建Twilio语音服务类,处理Token获取、初始化、通话操作:
import 'package:twilio_programmable_voice/twilio_programmable_voice.dart'; import 'package:cloud_functions/cloud_functions.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:permission_handler/permission_handler.dart'; class TwilioVoiceManager { // 获取Twilio Token Future<String> _fetchTwilioToken() async { final currentUser = FirebaseAuth.instance.currentUser; if (currentUser == null) throw Exception("用户未登录"); final callable = FirebaseFunctions.instance.httpsCallable('getTwilioToken'); final result = await callable(); return result.data['token']; } // 初始化Twilio语音服务 Future<void> initializeVoiceService() async { // 请求麦克风权限 final micPermission = await Permission.microphone.request(); if (micPermission.isDenied) throw Exception("麦克风权限被拒绝"); final token = await _fetchTwilioToken(); await TwilioProgrammableVoice.instance.initialize(token); // 监听通话状态 TwilioProgrammableVoice.instance.onConnect.listen((_) { print("通话已连接"); // 更新UI显示通话中 }); TwilioProgrammableVoice.instance.onDisconnect.listen((_) { print("通话已断开"); // 更新UI显示通话结束 }); TwilioProgrammableVoice.instance.onCallIncoming.listen((callEvent) { print("收到来自 ${callEvent.from} 的来电"); // 在这里实现来电UI,提供接听/拒绝按钮 // 接听:await TwilioProgrammableVoice.instance.acceptCall(callEvent.callSid); // 拒绝:await TwilioProgrammableVoice.instance.rejectCall(callEvent.callSid); }); } // 发起通话 Future<void> makeOutgoingCall(String targetIdentity) async { await TwilioProgrammableVoice.instance.makeCall(targetIdentity); } }
五、关键测试要点
- 确保Twilio控制台已完成配置:开通Voice服务、创建TwiML应用(获取Outgoing Application SID)、配置API Key/Secret。
- 必须使用真机测试,模拟器不支持语音通话功能。
- 测试前确认用户已通过Firebase Auth登录,否则无法获取Token。
内容的提问来源于stack exchange,提问作者J M Bhikadiya
相关产品推荐
相关产品推荐

