Commit e3c2820cfc9977f7aa833d1d7930557fb8a37347
1 parent
aa4e28be
feat:先声SDK逻辑调整
Showing
8 changed files
with
212 additions
and
76 deletions
ios/Runner.xcodeproj/project.pbxproj
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; | 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; |
| 11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; | 11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; |
| 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; | 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; |
| 13 | + 52450AF12A4C415B007B3E4B /* XSMessageMehtodChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52450AF02A4C415B007B3E4B /* XSMessageMehtodChannel.swift */; }; | ||
| 13 | 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */; }; | 14 | 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */; }; |
| 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; | 15 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; |
| 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; | 16 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; |
| @@ -52,6 +53,7 @@ | @@ -52,6 +53,7 @@ | ||
| 52 | 3563EC8D55A646823FD26A83 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; | 53 | 3563EC8D55A646823FD26A83 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; |
| 53 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; | 54 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; |
| 54 | 48BCA0827DCB98991774F5AC /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; }; | 55 | 48BCA0827DCB98991774F5AC /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; }; |
| 56 | + 52450AF02A4C415B007B3E4B /* XSMessageMehtodChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSMessageMehtodChannel.swift; sourceTree = "<group>"; }; | ||
| 55 | 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceXSMessageChannel.swift; sourceTree = "<group>"; }; | 57 | 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceXSMessageChannel.swift; sourceTree = "<group>"; }; |
| 56 | 6DEBBC1D861BE053F3ECE0B9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | 58 | 6DEBBC1D861BE053F3ECE0B9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 57 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; | 59 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; |
| @@ -152,6 +154,7 @@ | @@ -152,6 +154,7 @@ | ||
| 152 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, | 154 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, |
| 153 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, | 155 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, |
| 154 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, | 156 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, |
| 157 | + 52450AF02A4C415B007B3E4B /* XSMessageMehtodChannel.swift */, | ||
| 155 | 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */, | 158 | 525E17192A4BD03900104CDF /* VoiceXSMessageChannel.swift */, |
| 156 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, | 159 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, |
| 157 | ); | 160 | ); |
| @@ -397,6 +400,7 @@ | @@ -397,6 +400,7 @@ | ||
| 397 | buildActionMask = 2147483647; | 400 | buildActionMask = 2147483647; |
| 398 | files = ( | 401 | files = ( |
| 399 | 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */, | 402 | 525E171A2A4BD03900104CDF /* VoiceXSMessageChannel.swift in Sources */, |
| 403 | + 52450AF12A4C415B007B3E4B /* XSMessageMehtodChannel.swift in Sources */, | ||
| 400 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, | 404 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, |
| 401 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, | 405 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, |
| 402 | ); | 406 | ); |
ios/Runner/AppDelegate.swift
| @@ -10,6 +10,7 @@ import Flutter | @@ -10,6 +10,7 @@ import Flutter | ||
| 10 | GeneratedPluginRegistrant.register(with: self) | 10 | GeneratedPluginRegistrant.register(with: self) |
| 11 | let controller : FlutterViewController = window?.rootViewController as! FlutterViewController | 11 | let controller : FlutterViewController = window?.rootViewController as! FlutterViewController |
| 12 | _ = VoiceXSMessageChannel(messager: controller.binaryMessenger) | 12 | _ = VoiceXSMessageChannel(messager: controller.binaryMessenger) |
| 13 | + _ = XSMessageMehtodChannel(message: controller.binaryMessenger); | ||
| 13 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) | 14 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) |
| 14 | } | 15 | } |
| 15 | } | 16 | } |
ios/Runner/XSMessageMehtodChannel.swift
0 → 100644
| 1 | +// | ||
| 2 | +// XSMessageMehtodChannel.swift | ||
| 3 | +// Runner | ||
| 4 | +// | ||
| 5 | +// Created by MacBook Pro on 2023/6/28. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +import UIKit | ||
| 9 | + | ||
| 10 | +class XSMessageMehtodChannel: NSObject,SSOralEvaluatingManagerDelegate { | ||
| 11 | + var resultData:Dictionary<String, Any>? | ||
| 12 | + var messageChannel:FlutterMethodChannel? | ||
| 13 | + init(message:FlutterBinaryMessenger) { | ||
| 14 | + super.init() | ||
| 15 | + resultData = Dictionary() | ||
| 16 | + messageChannel = FlutterMethodChannel.init(name: "wow_english/sing_sound_method_channely", binaryMessenger: message) | ||
| 17 | + messageChannel!.setMethodCallHandler { call, result in | ||
| 18 | + self.handle(call, result) | ||
| 19 | + } | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + //配置评测信息 | ||
| 23 | + func setEvaluateConfig(dict:Dictionary<String, Any>) { | ||
| 24 | + let appKey = dict["appKey"] as? String | ||
| 25 | + let secretKey = dict["secretKey"] as? String | ||
| 26 | + let userId = dict.keys.contains("userId") ? dict["userId"] as! String:"" | ||
| 27 | + let frontTime = dict["frontTime"] as? TimeInterval | ||
| 28 | + let backTime = dict["frontTime"] as? TimeInterval | ||
| 29 | + let config = SSOralEvaluatingManagerConfig.init() | ||
| 30 | + config.appKey = appKey //"a418" | ||
| 31 | + config.secretKey = secretKey //"1a16f31f2611bf32fb7b3fc38f5b2c81"' | ||
| 32 | + config.frontTime = frontTime ?? 3 | ||
| 33 | + config.backTime = backTime ?? 3 | ||
| 34 | + SSOralEvaluatingManager.register(config) | ||
| 35 | + SSOralEvaluatingManager.share().register(.line, userId: userId) | ||
| 36 | + SSOralEvaluatingManager.share().delegate = self | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + //开始评测 | ||
| 40 | + func evaluateVioce(dict:Dictionary<String, Any>) { | ||
| 41 | + let text = dict["word"] as! String | ||
| 42 | + let type = dict["type"] as! Int | ||
| 43 | + let userId = dict["userId"] as! String | ||
| 44 | + let config = SSOralEvaluatingConfig() | ||
| 45 | + config.oralContent = text | ||
| 46 | + if (type == 0) { | ||
| 47 | + config.oralType = .word | ||
| 48 | + } else { | ||
| 49 | + config.oralType = .sentence | ||
| 50 | + } | ||
| 51 | + config.userId = userId | ||
| 52 | + SSOralEvaluatingManager.share().startEvaluateOral(with: config) | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + func handle(_ call: FlutterMethodCall,_ result: @escaping FlutterResult) { | ||
| 56 | + if (call.method == "initVoiceSdk") { | ||
| 57 | + self.setEvaluateConfig(dict:call.arguments as! Dictionary<String, Any>) | ||
| 58 | + return | ||
| 59 | + } | ||
| 60 | + if (call.method == "starVoice") { | ||
| 61 | + self.evaluateVioce(dict: call.arguments as! Dictionary<String, Any>) | ||
| 62 | + return | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + if (call.method == "stopVoice") { | ||
| 66 | + SSOralEvaluatingManager.share().stopEvaluate(); | ||
| 67 | + return | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + //评测结果回调 | ||
| 72 | + func evaluateResult() { | ||
| 73 | + messageChannel!.invokeMethod("voiceResult", arguments: resultData) | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + //SSOralEvaluatingManagerDelegate | ||
| 77 | + /** | ||
| 78 | + 评测开始 | ||
| 79 | + */ | ||
| 80 | + func oralEvaluatingDidStart() { | ||
| 81 | + print("评测开始") | ||
| 82 | + messageChannel!.invokeMethod("voiceStart", arguments: nil) | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + 评测停止 | ||
| 87 | + */ | ||
| 88 | + func oralEvaluatingDidStop() { | ||
| 89 | + print("评测结束") | ||
| 90 | + messageChannel!.invokeMethod("voiceEnd",arguments: nil) | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + /** | ||
| 94 | + 评测完成后的结果 | ||
| 95 | + */ | ||
| 96 | + func oralEvaluatingDidEnd(withResult result: [AnyHashable : Any]?, requestId request_id: String?) { | ||
| 97 | + print("评测完成结果") | ||
| 98 | + let resultDict:Dictionary<String, Any> = result?["result"] as! Dictionary | ||
| 99 | + resultData!["result"] = "1" | ||
| 100 | + //分数 | ||
| 101 | + resultData!["overall"] = resultDict["overall"] | ||
| 102 | + self.evaluateResult() | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + /** | ||
| 106 | + 评测失败回调 | ||
| 107 | + */ | ||
| 108 | + func oralEvaluatingDidEndError(_ error: Error?, requestId request_id: String?) { | ||
| 109 | + print("评测失败") | ||
| 110 | + messageChannel!.invokeMethod("voiceFail", arguments: error?.localizedDescription) | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + VAD(前置时间)超时回调 | ||
| 115 | + */ | ||
| 116 | + func oralEvaluatingDidVADFrontTimeOut() { | ||
| 117 | + print("前置超时--->取消") | ||
| 118 | + SSOralEvaluatingManager.share().cancelEvaluate() | ||
| 119 | + if(resultData?.keys.count == 0) { | ||
| 120 | + resultData!["result"] = "0" | ||
| 121 | + self.evaluateResult(); | ||
| 122 | + } | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + /** | ||
| 126 | + VAD(后置时间)超时回调 | ||
| 127 | + */ | ||
| 128 | + func oralEvaluatingDidVADBackTimeOut() { | ||
| 129 | + print("后置超时--->结束") | ||
| 130 | + ///结束回调 | ||
| 131 | + SSOralEvaluatingManager.share().stopEvaluate(); | ||
| 132 | + } | ||
| 133 | +} |
lib/pages/home/home_page.dart
| @@ -40,11 +40,6 @@ class _HomePageView extends StatelessWidget { | @@ -40,11 +40,6 @@ class _HomePageView extends StatelessWidget { | ||
| 40 | Navigator.of(AppRouter.context).pushNamed(AppRouteName.user); | 40 | Navigator.of(AppRouter.context).pushNamed(AppRouteName.user); |
| 41 | } else { | 41 | } else { |
| 42 | // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicPic); | 42 | // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicPic); |
| 43 | - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.topicWord); | ||
| 44 | - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.lookVideo); | ||
| 45 | - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.voicePic); | ||
| 46 | - // Navigator.of(AppRouter.context).pushNamed(AppRouteName.voiceWord); | ||
| 47 | - Navigator.of(AppRouter.context).pushNamed(AppRouteName.voiceAnswer); | ||
| 48 | } | 43 | } |
| 49 | } | 44 | } |
| 50 | 45 |
lib/pages/practice/bloc/topic_picture_bloc.dart
| @@ -35,19 +35,34 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | @@ -35,19 +35,34 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | ||
| 35 | 35 | ||
| 36 | bool get isVoicing => _isVoicing; | 36 | bool get isVoicing => _isVoicing; |
| 37 | 37 | ||
| 38 | - var messageChannel = const BasicMessageChannel('com.owEnglish.voiceXs.BasicMessageChannel', StandardMessageCodec()); | 38 | + late MethodChannel methodChannel; |
| 39 | 39 | ||
| 40 | - final audioPlayer = AudioPlayer(); | 40 | + late AudioPlayer audioPlayer; |
| 41 | 41 | ||
| 42 | TopicPictureBloc(this.pageController, this.modelCount) : super(TopicPictureInitial()) { | 42 | TopicPictureBloc(this.pageController, this.modelCount) : super(TopicPictureInitial()) { |
| 43 | on<CurrentPageIndexChangeEvent>(_pageControllerChange); | 43 | on<CurrentPageIndexChangeEvent>(_pageControllerChange); |
| 44 | - on<InitMessageChannelEvent>(_initMessageChannelCall); | ||
| 45 | - on<RequestDataEvent>(_requestData); | ||
| 46 | on<SelectItemEvent>(_selectItemLoad); | 44 | on<SelectItemEvent>(_selectItemLoad); |
| 47 | - on<VoiceXsTestEvent>(_voiceXsTest); | ||
| 48 | - on<VoiceResultEvent>(_voiceResult); | 45 | + on<RequestDataEvent>(_requestData); |
| 46 | + on<XSVoiceTestEvent>(_voiceXsTest); | ||
| 47 | + on<XSVoiceResultEvent>(_voiceXsResult); | ||
| 48 | + on<XSVoiceInitEvent>(_initVoiceSdk); | ||
| 49 | on<TopicPictureEvent>((event, emit) { | 49 | on<TopicPictureEvent>((event, emit) { |
| 50 | + //音频播放器 | ||
| 51 | + audioPlayer = AudioPlayer(); | ||
| 52 | + audioPlayer.onPlayerStateChanged.listen((event) { | ||
| 53 | + if (event == PlayerState.stopped) { | ||
| 54 | + | ||
| 55 | + } | ||
| 56 | + }); | ||
| 57 | + | ||
| 50 | 58 | ||
| 59 | + methodChannel = const MethodChannel('wow_english/sing_sound_method_channely'); | ||
| 60 | + methodChannel.invokeMethod('initVoiceSdk',{}); | ||
| 61 | + methodChannel.setMethodCallHandler((call) async { | ||
| 62 | + if (call.method == 'voiceResult') {//评测结束 | ||
| 63 | + add(XSVoiceResultEvent(call.arguments)); | ||
| 64 | + } | ||
| 65 | + }); | ||
| 51 | }); | 66 | }); |
| 52 | } | 67 | } |
| 53 | 68 | ||
| @@ -58,6 +73,7 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | @@ -58,6 +73,7 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | ||
| 58 | return super.close(); | 73 | return super.close(); |
| 59 | } | 74 | } |
| 60 | 75 | ||
| 76 | + ///请求数据 | ||
| 61 | void _requestData(RequestDataEvent event,Emitter<TopicPictureState> emitter) async { | 77 | void _requestData(RequestDataEvent event,Emitter<TopicPictureState> emitter) async { |
| 62 | try { | 78 | try { |
| 63 | await loading(() async { | 79 | await loading(() async { |
| @@ -71,6 +87,12 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | @@ -71,6 +87,12 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | ||
| 71 | } | 87 | } |
| 72 | } | 88 | } |
| 73 | 89 | ||
| 90 | + ///初始化SDK | ||
| 91 | + _initVoiceSdk(XSVoiceInitEvent event,Emitter<TopicPictureState> emitter) async { | ||
| 92 | + methodChannel.invokeMethod('initVoiceSdk',event.data); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + ///页面切换 | ||
| 74 | void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async { | 96 | void _pageControllerChange(CurrentPageIndexChangeEvent event,Emitter<TopicPictureState> emitter) async { |
| 75 | _currentPage = event.pageIndex; | 97 | _currentPage = event.pageIndex; |
| 76 | final topics = _entity?.topics?[_currentPage]; | 98 | final topics = _entity?.topics?[_currentPage]; |
| @@ -87,15 +109,25 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | @@ -87,15 +109,25 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | ||
| 87 | emitter(CurrentPageIndexState()); | 109 | emitter(CurrentPageIndexState()); |
| 88 | } | 110 | } |
| 89 | 111 | ||
| 112 | + ///选择 | ||
| 90 | void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async { | 113 | void _selectItemLoad(SelectItemEvent event,Emitter<TopicPictureState> emitter) async { |
| 91 | _selectItem = event.selectIndex; | 114 | _selectItem = event.selectIndex; |
| 92 | emitter(SelectItemChangeState()); | 115 | emitter(SelectItemChangeState()); |
| 93 | } | 116 | } |
| 94 | 117 | ||
| 95 | - ///messageChannel回调 | ||
| 96 | - Future messageResultHandler(message,Emitter<TopicPictureState> emitter) async { | ||
| 97 | - EasyLoading.dismiss(); | ||
| 98 | - final Map args = message as Map; | 118 | + ///先声测试 |
| 119 | + void _voiceXsTest(XSVoiceTestEvent event,Emitter<TopicPictureState> emitter) async { | ||
| 120 | + EasyLoading.show(status: '录音中....'); | ||
| 121 | + methodChannel.invokeMethod( | ||
| 122 | + 'startRecord', | ||
| 123 | + {'word':event.testWord,'type':event.type,'userId':event.userId.toString()} | ||
| 124 | + ); | ||
| 125 | + _isVoicing = true; | ||
| 126 | + emitter(XSVoiceTestState()); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + void _voiceXsResult(XSVoiceResultEvent event,Emitter<TopicPictureState> emitter) async { | ||
| 130 | + final Map args = event.message as Map; | ||
| 99 | final result = args['result'] as String; | 131 | final result = args['result'] as String; |
| 100 | if (result == '1') { | 132 | if (result == '1') { |
| 101 | final overall = args['overall'].toString(); | 133 | final overall = args['overall'].toString(); |
| @@ -103,35 +135,7 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | @@ -103,35 +135,7 @@ class TopicPictureBloc extends Bloc<TopicPictureEvent, TopicPictureState> { | ||
| 103 | } else { | 135 | } else { |
| 104 | EasyLoading.showToast('测评失败',duration: const Duration(seconds: 10)); | 136 | EasyLoading.showToast('测评失败',duration: const Duration(seconds: 10)); |
| 105 | } | 137 | } |
| 106 | - if (kDebugMode) { | ||
| 107 | - print('是否被移除>>>>>$emitter'); | ||
| 108 | - } | ||
| 109 | - _isVoicing = false; | ||
| 110 | - } | ||
| 111 | - | ||
| 112 | - Future _initMessageChannelCall(InitMessageChannelEvent event,Emitter<TopicPictureState> emitter) async { | ||
| 113 | - messageChannel.setMessageHandler((message) => | ||
| 114 | - messageResultHandler(message, emitter) | ||
| 115 | - ); | ||
| 116 | - | ||
| 117 | - audioPlayer.onPlayerStateChanged.listen((event) { | ||
| 118 | - if (event == PlayerState.stopped) { | ||
| 119 | - if (kDebugMode) { | ||
| 120 | - print('播放结束'); | ||
| 121 | - } | ||
| 122 | - } | ||
| 123 | - }); | ||
| 124 | - } | ||
| 125 | - | ||
| 126 | - void _voiceXsTest(VoiceXsTestEvent event,Emitter<TopicPictureState> emitter) async { | ||
| 127 | - EasyLoading.show(status: '录音中....'); | ||
| 128 | - messageChannel.send({'word':event.testWord,'type':event.type,'userId':event.userId.toString()}); | ||
| 129 | - _isVoicing = true; | ||
| 130 | - emitter(VoiceXsTestState()); | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - void _voiceResult(VoiceResultEvent event,Emitter<TopicPictureState> emitter) async { | ||
| 134 | _isVoicing = false; | 138 | _isVoicing = false; |
| 135 | - emitter(VoiceXsTestState()); | 139 | + emitter(XSVoiceTestState()); |
| 136 | } | 140 | } |
| 137 | } | 141 | } |
lib/pages/practice/bloc/topic_picture_event.dart
| @@ -5,17 +5,24 @@ abstract class TopicPictureEvent {} | @@ -5,17 +5,24 @@ abstract class TopicPictureEvent {} | ||
| 5 | 5 | ||
| 6 | class RequestDataEvent extends TopicPictureEvent {} | 6 | class RequestDataEvent extends TopicPictureEvent {} |
| 7 | 7 | ||
| 8 | -///初始化消息回调 | ||
| 9 | -class InitMessageChannelEvent extends TopicPictureEvent {} | 8 | +///初始化先声SDK |
| 9 | +class XSVoiceInitEvent extends TopicPictureEvent { | ||
| 10 | + final Map data; | ||
| 11 | + XSVoiceInitEvent(this.data); | ||
| 12 | +} | ||
| 10 | 13 | ||
| 11 | -class VoiceResultEvent extends TopicPictureEvent {} | 14 | +///评测结果 |
| 15 | +class XSVoiceResultEvent extends TopicPictureEvent { | ||
| 16 | + final dynamic message; | ||
| 17 | + XSVoiceResultEvent(this.message); | ||
| 18 | +} | ||
| 12 | 19 | ||
| 13 | ///先声测试 | 20 | ///先声测试 |
| 14 | -class VoiceXsTestEvent extends TopicPictureEvent { | 21 | +class XSVoiceTestEvent extends TopicPictureEvent { |
| 15 | final String testWord; | 22 | final String testWord; |
| 16 | final int type; | 23 | final int type; |
| 17 | final int userId; | 24 | final int userId; |
| 18 | - VoiceXsTestEvent(this.testWord,this.type,this.userId); | 25 | + XSVoiceTestEvent(this.testWord,this.type,this.userId); |
| 19 | } | 26 | } |
| 20 | 27 | ||
| 21 | class CurrentPageIndexChangeEvent extends TopicPictureEvent { | 28 | class CurrentPageIndexChangeEvent extends TopicPictureEvent { |
lib/pages/practice/bloc/topic_picture_state.dart
| @@ -5,7 +5,7 @@ abstract class TopicPictureState {} | @@ -5,7 +5,7 @@ abstract class TopicPictureState {} | ||
| 5 | 5 | ||
| 6 | class RequestDataState extends TopicPictureState {} | 6 | class RequestDataState extends TopicPictureState {} |
| 7 | 7 | ||
| 8 | -class VoiceXsTestState extends TopicPictureState {} | 8 | +class XSVoiceTestState extends TopicPictureState {} |
| 9 | 9 | ||
| 10 | class TopicPictureInitial extends TopicPictureState {} | 10 | class TopicPictureInitial extends TopicPictureState {} |
| 11 | 11 |
lib/pages/practice/topic_picture_page.dart
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | import 'package:flutter_bloc/flutter_bloc.dart'; | 2 | import 'package:flutter_bloc/flutter_bloc.dart'; |
| 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 4 | -import 'package:wow_english/common/blocs/cachebloc/cache_bloc.dart'; | 4 | +import 'package:wow_english/common/core/user_util.dart'; |
| 5 | import 'package:wow_english/common/extension/string_extension.dart'; | 5 | import 'package:wow_english/common/extension/string_extension.dart'; |
| 6 | import 'package:wow_english/common/widgets/ow_image_widget.dart'; | 6 | import 'package:wow_english/common/widgets/ow_image_widget.dart'; |
| 7 | import 'package:wow_english/models/course_process_entity.dart'; | 7 | import 'package:wow_english/models/course_process_entity.dart'; |
| @@ -20,7 +20,13 @@ class TopicPicturePage extends StatelessWidget { | @@ -20,7 +20,13 @@ class TopicPicturePage extends StatelessWidget { | ||
| 20 | 3 | 20 | 3 |
| 21 | ) | 21 | ) |
| 22 | ..add(RequestDataEvent()) | 22 | ..add(RequestDataEvent()) |
| 23 | - ..add(InitMessageChannelEvent()), | 23 | + ..add(XSVoiceInitEvent( |
| 24 | + { | ||
| 25 | + 'appKey':'a418', | ||
| 26 | + 'secretKey':'1a16f31f2611bf32fb7b3fc38f5b2c81', | ||
| 27 | + 'userId':UserUtil.getUser()!.id | ||
| 28 | + } | ||
| 29 | + )), | ||
| 24 | child: _TopicPicturePage(), | 30 | child: _TopicPicturePage(), |
| 25 | ); | 31 | ); |
| 26 | } | 32 | } |
| @@ -32,7 +38,11 @@ class _TopicPicturePage extends StatelessWidget { | @@ -32,7 +38,11 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 32 | return BlocListener<TopicPictureBloc,TopicPictureState>( | 38 | return BlocListener<TopicPictureBloc,TopicPictureState>( |
| 33 | listener: (context, state){ | 39 | listener: (context, state){ |
| 34 | if (state is RequestDataState) { | 40 | if (state is RequestDataState) { |
| 35 | - context.read<TopicPictureBloc>().add(CurrentPageIndexChangeEvent(0)); | 41 | + // context.read<TopicPictureBloc>().add(CurrentPageIndexChangeEvent(0)); |
| 42 | + } | ||
| 43 | + | ||
| 44 | + if (state is XSVoiceTestState) { | ||
| 45 | + | ||
| 36 | } | 46 | } |
| 37 | }, | 47 | }, |
| 38 | child: _topicPictureView(), | 48 | child: _topicPictureView(), |
| @@ -50,7 +60,10 @@ class _TopicPicturePage extends StatelessWidget { | @@ -50,7 +60,10 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 50 | children: [ | 60 | children: [ |
| 51 | PracticeHeaderWidget( | 61 | PracticeHeaderWidget( |
| 52 | title: '${bloc.currentPage}/${bloc.entity?.topics?.length}', | 62 | title: '${bloc.currentPage}/${bloc.entity?.topics?.length}', |
| 53 | - onTap: (){Navigator.pop(context);}, | 63 | + onTap: (){ |
| 64 | + bloc.add(XSVoiceTestEvent('Hello', 0,UserUtil.getUser()!.id)); | ||
| 65 | + // Navigator.pop(context); | ||
| 66 | + }, | ||
| 54 | ), | 67 | ), |
| 55 | Expanded( | 68 | Expanded( |
| 56 | child: PageView.builder( | 69 | child: PageView.builder( |
| @@ -332,27 +345,6 @@ class _TopicPicturePage extends StatelessWidget { | @@ -332,27 +345,6 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 332 | return _decodeVoiceWordImageWidget(index, topics!.topicAnswerList![index]); | 345 | return _decodeVoiceWordImageWidget(index, topics!.topicAnswerList![index]); |
| 333 | }), | 346 | }), |
| 334 | ), | 347 | ), |
| 335 | - // Row( | ||
| 336 | - // mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
| 337 | - // children: [ | ||
| 338 | - // Offstage( | ||
| 339 | - // offstage: topics.topicAnswerList!.length <= 1, | ||
| 340 | - // child: _decodeVoiceWordImageWidget(1,topics.topicAnswerList![0]), | ||
| 341 | - // ), | ||
| 342 | - // Offstage( | ||
| 343 | - // offstage: topics.topicAnswerList!.length <= 2, | ||
| 344 | - // child: _decodeVoiceWordImageWidget(2,topics.topicAnswerList![1]), | ||
| 345 | - // ), | ||
| 346 | - // // Offstage( | ||
| 347 | - // // offstage: topics.topicAnswerList!.length <= 3, | ||
| 348 | - // // child: _decodeVoiceWordImageWidget(3,topics.topicAnswerList![2]), | ||
| 349 | - // // ), | ||
| 350 | - // // Offstage( | ||
| 351 | - // // offstage: topics.topicAnswerList!.length <= 4, | ||
| 352 | - // // child: _decodeVoiceWordImageWidget(4,topics.topicAnswerList![3]), | ||
| 353 | - // // ) | ||
| 354 | - // ], | ||
| 355 | - // ) | ||
| 356 | ], | 348 | ], |
| 357 | ), | 349 | ), |
| 358 | ); | 350 | ); |
| @@ -443,7 +435,7 @@ class _TopicPicturePage extends StatelessWidget { | @@ -443,7 +435,7 @@ class _TopicPicturePage extends StatelessWidget { | ||
| 443 | if (bloc.isVoicing) { | 435 | if (bloc.isVoicing) { |
| 444 | return; | 436 | return; |
| 445 | } | 437 | } |
| 446 | - bloc.add(VoiceXsTestEvent('Hello', 0,context.read<CacheBloc>().userEntity!.id)); | 438 | + bloc.add(XSVoiceTestEvent('Hello', 0,UserUtil.getUser()!.id)); |
| 447 | }, | 439 | }, |
| 448 | child: Image.asset( | 440 | child: Image.asset( |
| 449 | 'micro_phone'.assetPng, | 441 | 'micro_phone'.assetPng, |