Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
F
flutter-chat
Project
Project
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
Graph
比较
统计图
议题
0
议题
0
列表
看板
标记
Milestones
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
songchuancai
flutter-chat
Commits
8631150a
提交
8631150a
authored
11月 11, 2024
作者:
songchuancai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
优化语音功能
上级
104d31dd
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
86 行增加
和
28 行删除
+86
-28
build.gradle
android/app/build.gradle
+1
-1
AndroidManifest.xml
android/app/src/main/AndroidManifest.xml
+2
-0
home_page.dart
lib/home_page.dart
+83
-27
没有找到文件。
android/app/build.gradle
浏览文件 @
8631150a
...
@@ -8,7 +8,7 @@ if (localPropertiesFile.exists()) {
...
@@ -8,7 +8,7 @@ if (localPropertiesFile.exists()) {
def
flutterRoot
=
localProperties
.
getProperty
(
'flutter.sdk'
)
def
flutterRoot
=
localProperties
.
getProperty
(
'flutter.sdk'
)
if
(
flutterRoot
==
null
)
{
if
(
flutterRoot
==
null
)
{
throw
new
GradleException
(
"Flutter SDK not found. Define location with flutter.sdk in the local.properties file."
)
throw
new
FileNotFoundException
(
"Flutter SDK not found. Define location with flutter.sdk in the local.properties file."
)
}
}
def
flutterVersionCode
=
localProperties
.
getProperty
(
'flutter.versionCode'
)
def
flutterVersionCode
=
localProperties
.
getProperty
(
'flutter.versionCode'
)
...
...
android/app/src/main/AndroidManifest.xml
浏览文件 @
8631150a
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
<uses-permission
android:name=
"android.permission.BLUETOOTH"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH_ADMIN"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH_ADMIN"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH_CONNECT"
/>
<uses-permission
android:name=
"android.permission.BLUETOOTH_CONNECT"
/>
<uses-permission
android:name=
"android.permission.FOREGROUND_SERVICE"
/>
<uses-permission
android:name=
"android.permission.WAKE_LOCK"
/>
<queries>
<queries>
<intent>
<intent>
<action
android:name=
"android.speech.RecognitionService"
/>
<action
android:name=
"android.speech.RecognitionService"
/>
...
...
lib/home_page.dart
浏览文件 @
8631150a
...
@@ -92,6 +92,8 @@ class _HomePageState extends State<HomePage> {
...
@@ -92,6 +92,8 @@ class _HomePageState extends State<HomePage> {
int
_currentIndex
=
0
;
int
_currentIndex
=
0
;
bool
_hasSpeechPermission
=
false
;
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
...
@@ -162,15 +164,47 @@ class _HomePageState extends State<HomePage> {
...
@@ -162,15 +164,47 @@ class _HomePageState extends State<HomePage> {
}
}
Future
<
void
>
initSpeechToText
()
async
{
Future
<
void
>
initSpeechToText
()
async
{
await
speechToText
.
initialize
();
try
{
_hasSpeechPermission
=
await
speechToText
.
initialize
(
onStatus:
(
status
)
{
print
(
'语音状态:
$status
'
);
if
(
status
==
'notListening'
)
{
setState
(()
=>
_isListeningPressed
=
false
);
}
},
onError:
(
error
)
{
print
(
'语音错误:
$error
'
);
setState
(()
=>
_isListeningPressed
=
false
);
_showErrorDialog
(
'语音初始化失败,请检查麦克风权限'
);
},
);
}
catch
(
e
)
{
print
(
'语音初始化错误:
$e
'
);
_hasSpeechPermission
=
false
;
}
setState
(()
{});
setState
(()
{});
}
}
Future
<
void
>
startListening
()
async
{
Future
<
void
>
startListening
()
async
{
await
speechToText
.
listen
(
onResult:
onSpeechResult
);
if
(!
_hasSpeechPermission
)
{
_showErrorDialog
(
'请先授予麦克风权限'
);
setState
(()
=>
_isListeningPressed
=
false
);
return
;
}
setState
(()
{});
try
{
await
speechToText
.
listen
(
onResult:
onSpeechResult
,
localeId:
'zh_CN'
,
listenMode:
ListenMode
.
confirmation
,
cancelOnError:
true
,
partialResults:
true
,
);
}
catch
(
e
)
{
print
(
'开始录音失败:
$e
'
);
setState
(()
=>
_isListeningPressed
=
false
);
_showErrorDialog
(
'启动语音识别失败,请重试'
);
}
}
}
Future
<
void
>
stopListening
()
async
{
Future
<
void
>
stopListening
()
async
{
...
@@ -372,38 +406,32 @@ class _HomePageState extends State<HomePage> {
...
@@ -372,38 +406,32 @@ class _HomePageState extends State<HomePage> {
Expanded
(
Expanded
(
child:
_isVoiceMode
child:
_isVoiceMode
?
GestureDetector
(
?
GestureDetector
(
onLongPressStart:
(
_
)
async
{
onTap:
()
async
{
if
(!
_isListeningPressed
)
{
// 开始录音
setState
(()
{
setState
(()
{
_isListeningPressed
=
true
;
_isListeningPressed
=
true
;
_currentVoiceText
=
''
;
_currentVoiceText
=
''
;
});
});
await
startListening
();
await
startListening
();
},
}
else
{
onLongPressEnd:
(
_
)
async
{
// 停止录音
setState
(()
=>
_isListeningPressed
=
false
);
setState
(()
=>
_isListeningPressed
=
false
);
await
stopListening
();
await
stopListening
();
final
finalVoiceText
=
_currentVoiceText
;
// 确保有语音文本才处理
if
(
_currentVoiceText
.
isNotEmpty
)
{
if
(
finalVoiceText
.
isNotEmpty
)
{
setState
(()
{
setState
(()
{
messages
.
add
(
ChatMessage
(
messages
.
add
(
ChatMessage
(
text:
finalVoiceText
,
text:
_currentVoiceText
,
isUserMessage:
true
,
isUserMessage:
true
,
));
));
_isLoading
=
true
;
_isLoading
=
true
;
});
});
await
_processAIResponse
(
_currentVoiceText
);
await
_processAIResponse
(
finalVoiceText
);
}
setState
(()
=>
_currentVoiceText
=
''
);
}
}
setState
(()
{
_currentVoiceText
=
''
;
});
},
},
child:
Container
(
child:
Container
(
padding:
const
EdgeInsets
.
symmetric
(
padding:
const
EdgeInsets
.
symmetric
(
...
@@ -414,12 +442,20 @@ class _HomePageState extends State<HomePage> {
...
@@ -414,12 +442,20 @@ class _HomePageState extends State<HomePage> {
color:
Colors
.
grey
[
100
],
color:
Colors
.
grey
[
100
],
borderRadius:
BorderRadius
.
circular
(
25
),
borderRadius:
BorderRadius
.
circular
(
25
),
),
),
child:
Text
(
child:
Row
(
mainAxisSize:
MainAxisSize
.
min
,
children:
[
Icon
(
_isListeningPressed
?
Icons
.
stop
:
Icons
.
mic
,
color:
_isListeningPressed
?
Pallete
.
firstSuggestionBoxColor
:
Colors
.
grey
[
600
],
),
const
SizedBox
(
width:
8
),
Text
(
_isListeningPressed
_isListeningPressed
?
(
_currentVoiceText
.
isEmpty
?
(
_currentVoiceText
.
isEmpty
?
'点击停止'
:
_currentVoiceText
)
?
'正在聆听...'
:
'点击说话'
,
:
_currentVoiceText
)
:
'按住说话'
,
textAlign:
TextAlign
.
center
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
style:
TextStyle
(
color:
_isListeningPressed
color:
_isListeningPressed
...
@@ -427,6 +463,8 @@ class _HomePageState extends State<HomePage> {
...
@@ -427,6 +463,8 @@ class _HomePageState extends State<HomePage> {
:
Colors
.
grey
[
600
],
:
Colors
.
grey
[
600
],
),
),
),
),
],
),
),
),
)
)
:
TextField
(
:
TextField
(
...
@@ -703,7 +741,7 @@ class _HomePageState extends State<HomePage> {
...
@@ -703,7 +741,7 @@ class _HomePageState extends State<HomePage> {
),
),
const
SizedBox
(
width:
8
),
const
SizedBox
(
width:
8
),
Text
(
Text
(
'
退出登录'
,
'
出登录'
,
style:
TextStyle
(
style:
TextStyle
(
color:
Colors
.
red
[
700
],
color:
Colors
.
red
[
700
],
fontSize:
16
,
fontSize:
16
,
...
@@ -724,6 +762,22 @@ class _HomePageState extends State<HomePage> {
...
@@ -724,6 +762,22 @@ class _HomePageState extends State<HomePage> {
);
);
}
}
void
_showErrorDialog
(
String
message
)
{
showDialog
(
context:
context
,
builder:
(
context
)
=>
AlertDialog
(
title:
const
Text
(
'提示'
),
content:
Text
(
message
),
actions:
[
TextButton
(
onPressed:
()
=>
Navigator
.
pop
(
context
),
child:
const
Text
(
'确定'
),
),
],
),
);
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
return
Scaffold
(
...
@@ -850,3 +904,4 @@ class _HomePageState extends State<HomePage> {
...
@@ -850,3 +904,4 @@ class _HomePageState extends State<HomePage> {
);
);
}
}
}
}
\ No newline at end of file
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论