speechrecognizer 0.0.1
speechrecognizer: ^0.0.1 copied to clipboard
Flutter 语音识别插件,支持 HarmonyOS/OpenHarmony,基于系统 CoreSpeechKit 实现实时语音转文字与麦克风权限管理。
example/lib/main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:speechrecognizer/speechrecognizer.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
String _recognizedText = '';
String _statusText = '未开始';
bool _isListening = false;
bool _permissionGranted = false;
final List<String> _logs = [];
final _speechrecognizerPlugin = Speechrecognizer();
@override
void initState() {
super.initState();
_initPlugin();
}
Future<void> _initPlugin() async {
// 获取平台版本
try {
_platformVersion =
await _speechrecognizerPlugin.getPlatformVersion() ??
'Unknown platform version';
} on PlatformException {
_platformVersion = 'Failed to get platform version.';
}
// 设置语音识别监听
_speechrecognizerPlugin.setListeners(
onStart: (result) {
_addLog('识别开始: sessionId=${result.sessionId}');
if (mounted) {
setState(() {
_statusText = '正在识别...';
_isListening = true;
});
}
},
onResult: (result) {
_addLog('识别结果: "${result.text}" isFinal=${result.isFinal} isLast=${result.isLast}');
if (mounted) {
setState(() {
_recognizedText = result.text;
});
}
},
onComplete: (result) {
_addLog('识别完成: sessionId=${result.sessionId} message=${result.message}');
if (mounted) {
setState(() {
_statusText = '识别完成';
_isListening = false;
});
}
},
onError: (error) {
_addLog('识别出错: code=${error.errorCode} msg=${error.errorMessage}');
if (mounted) {
setState(() {
_statusText = '出错: ${error.errorMessage}';
_isListening = false;
});
}
},
);
if (mounted) {
setState(() {});
}
}
void _addLog(String msg) {
debugPrint('[SpeechRecognizer] $msg');
if (mounted) {
setState(() {
_logs.insert(0, '${DateTime.now().toString().substring(11, 19)} $msg');
if (_logs.length > 50) _logs.removeLast();
});
}
}
Future<void> _requestPermission() async {
try {
final granted = await _speechrecognizerPlugin.requestPermission();
_addLog('权限请求结果: $granted');
if (mounted) {
setState(() {
_permissionGranted = granted;
});
}
} catch (e) {
_addLog('权限请求异常: $e');
}
}
Future<void> _startRecognition() async {
setState(() {
_recognizedText = '';
_statusText = '启动中...';
});
try {
final sessionId = await _speechrecognizerPlugin.startSpeechRecognition(
language: 'zh-CN',
);
_addLog('开始识别, sessionId=$sessionId');
} catch (e) {
_addLog('启动识别失败: $e');
if (mounted) {
setState(() {
_statusText = '启动失败';
_isListening = false;
});
}
}
}
Future<void> _stopRecognition() async {
try {
await _speechrecognizerPlugin.stopSpeechRecognition();
_addLog('已停止识别');
if (mounted) {
setState(() {
_statusText = '已停止';
_isListening = false;
});
}
} catch (e) {
_addLog('停止识别失败: $e');
}
}
@override
void dispose() {
_speechrecognizerPlugin.removeListeners();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('语音识别插件示例'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('平台: $_platformVersion',
style: const TextStyle(fontSize: 14, color: Colors.grey)),
const SizedBox(height: 12),
// 权限按钮
ElevatedButton.icon(
onPressed: _requestPermission,
icon: Icon(_permissionGranted ? Icons.check_circle : Icons.mic),
label: Text(_permissionGranted ? '麦克风权限已授予' : '请求麦克风权限'),
style: ElevatedButton.styleFrom(
backgroundColor:
_permissionGranted ? Colors.green : Colors.blue,
foregroundColor: Colors.white,
),
),
const SizedBox(height: 16),
// 状态
Row(
children: [
if (_isListening)
const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 2),
),
if (_isListening) const SizedBox(width: 8),
Text('状态: $_statusText',
style: const TextStyle(fontSize: 16)),
],
),
const SizedBox(height: 12),
// 识别结果
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey[300]!),
),
constraints: const BoxConstraints(minHeight: 80),
child: Text(
_recognizedText.isEmpty ? '识别结果将显示在此处...' : _recognizedText,
style: TextStyle(
fontSize: 18,
color:
_recognizedText.isEmpty ? Colors.grey : Colors.black87,
),
),
),
const SizedBox(height: 16),
// 操作按钮
Row(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: _isListening ? null : _startRecognition,
icon: const Icon(Icons.mic),
label: const Text('开始识别'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
),
const SizedBox(width: 12),
Expanded(
child: ElevatedButton.icon(
onPressed: _isListening ? _stopRecognition : null,
icon: const Icon(Icons.stop),
label: const Text('停止识别'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
),
],
),
const SizedBox(height: 16),
// 日志区域
const Text('日志:', style: TextStyle(fontWeight: FontWeight.bold)),
const SizedBox(height: 4),
Expanded(
child: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.circular(8),
),
child: ListView.builder(
itemCount: _logs.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 1),
child: Text(
_logs[index],
style: const TextStyle(
fontSize: 12,
color: Colors.greenAccent,
fontFamily: 'monospace',
),
),
);
},
),
),
),
],
),
),
),
);
}
}