You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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端配置

  1. 在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" />
  1. 在<application>标签内添加Twilio服务:
<service android:name="com.twilio.voice.VoiceService" android:exported="false" />

iOS端配置

  1. 在ios/Runner/Info.plist中添加权限描述和后台模式:
<key>NSMicrophoneUsageDescription</key>
<string>需要麦克风权限进行语音通话</string>
<key>UIBackgroundModes</key>
<array>
  <string>voip</string>
</array>
  1. 打开Xcode,进入Runner项目的Signing & Capabilities页面,添加Background Modes并勾选Voice over IP选项。

三、通过Firebase云函数生成Twilio Token

Twilio语音通话需要Access Token鉴权,用你已有的Cloud Functions实现Token生成:

  1. 在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() };
});
  1. 部署该函数到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);
  }
}

五、关键测试要点

  1. 确保Twilio控制台已完成配置:开通Voice服务、创建TwiML应用(获取Outgoing Application SID)、配置API Key/Secret。
  2. 必须使用真机测试,模拟器不支持语音通话功能。
  3. 测试前确认用户已通过Firebase Auth登录,否则无法获取Token。

内容的提问来源于stack exchange,提问作者J M Bhikadiya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 08:18:20