Commit 7868fbc46ab4801ff0c32292fab2648080528964

Authored by weixin_45529955
1 parent f82296dd

语音相关功能未OK

Too many changes to show.

To preserve performance only 10 of 10+ files are displayed.

@@ -243,6 +243,26 @@ @@ -243,6 +243,26 @@
243 "flutterMode": "release" 243 "flutterMode": "release"
244 }, 244 },
245 { 245 {
  246 + "name": "flutter_tts_ohos",
  247 + "cwd": "library/flutter_tts_ohos",
  248 + "request": "launch",
  249 + "type": "dart"
  250 + },
  251 + {
  252 + "name": "flutter_tts_ohos (profile mode)",
  253 + "cwd": "library/flutter_tts_ohos",
  254 + "request": "launch",
  255 + "type": "dart",
  256 + "flutterMode": "profile"
  257 + },
  258 + {
  259 + "name": "flutter_tts_ohos (release mode)",
  260 + "cwd": "library/flutter_tts_ohos",
  261 + "request": "launch",
  262 + "type": "dart",
  263 + "flutterMode": "release"
  264 + },
  265 + {
246 "name": "fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new", 266 "name": "fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new",
247 "cwd": "library/fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new", 267 "cwd": "library/fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new",
248 "request": "launch", 268 "request": "launch",
@@ -323,6 +343,26 @@ @@ -323,6 +343,26 @@
323 "flutterMode": "release" 343 "flutterMode": "release"
324 }, 344 },
325 { 345 {
  346 + "name": "speech_to_text_wdn_ohos",
  347 + "cwd": "library/speech_to_text_wdn_ohos",
  348 + "request": "launch",
  349 + "type": "dart"
  350 + },
  351 + {
  352 + "name": "speech_to_text_wdn_ohos (profile mode)",
  353 + "cwd": "library/speech_to_text_wdn_ohos",
  354 + "request": "launch",
  355 + "type": "dart",
  356 + "flutterMode": "profile"
  357 + },
  358 + {
  359 + "name": "speech_to_text_wdn_ohos (release mode)",
  360 + "cwd": "library/speech_to_text_wdn_ohos",
  361 + "request": "launch",
  362 + "type": "dart",
  363 + "flutterMode": "release"
  364 + },
  365 + {
326 "name": "table_calendar-2.3.3", 366 "name": "table_calendar-2.3.3",
327 "cwd": "library/table_calendar-2.3.3", 367 "cwd": "library/table_calendar-2.3.3",
328 "request": "launch", 368 "request": "launch",
@@ -524,6 +564,26 @@ @@ -524,6 +564,26 @@
524 }, 564 },
525 { 565 {
526 "name": "example", 566 "name": "example",
  567 + "cwd": "library/flutter_tts_ohos/example",
  568 + "request": "launch",
  569 + "type": "dart"
  570 + },
  571 + {
  572 + "name": "example (profile mode)",
  573 + "cwd": "library/flutter_tts_ohos/example",
  574 + "request": "launch",
  575 + "type": "dart",
  576 + "flutterMode": "profile"
  577 + },
  578 + {
  579 + "name": "example (release mode)",
  580 + "cwd": "library/flutter_tts_ohos/example",
  581 + "request": "launch",
  582 + "type": "dart",
  583 + "flutterMode": "release"
  584 + },
  585 + {
  586 + "name": "example",
527 "cwd": "library/fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new/example", 587 "cwd": "library/fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new/example",
528 "request": "launch", 588 "request": "launch",
529 "type": "dart" 589 "type": "dart"
@@ -644,6 +704,26 @@ @@ -644,6 +704,26 @@
644 }, 704 },
645 { 705 {
646 "name": "example", 706 "name": "example",
  707 + "cwd": "library/speech_to_text_wdn_ohos/example",
  708 + "request": "launch",
  709 + "type": "dart"
  710 + },
  711 + {
  712 + "name": "example (profile mode)",
  713 + "cwd": "library/speech_to_text_wdn_ohos/example",
  714 + "request": "launch",
  715 + "type": "dart",
  716 + "flutterMode": "profile"
  717 + },
  718 + {
  719 + "name": "example (release mode)",
  720 + "cwd": "library/speech_to_text_wdn_ohos/example",
  721 + "request": "launch",
  722 + "type": "dart",
  723 + "flutterMode": "release"
  724 + },
  725 + {
  726 + "name": "example",
647 "cwd": "library/table_calendar-3.1.3/example", 727 "cwd": "library/table_calendar-3.1.3/example",
648 "request": "launch", 728 "request": "launch",
649 "type": "dart" 729 "type": "dart"
@@ -8,8 +8,14 @@ @@ -8,8 +8,14 @@
8 additional functionality it is fine to subclass or reimplement 8 additional functionality it is fine to subclass or reimplement
9 FlutterApplication and put your custom class here. --> 9 FlutterApplication and put your custom class here. -->
10 10
11 -  
12 - <!-- 【必须】 移动推送 TPNS SDK 所需权限 --> 11 +
  12 +
  13 +
  14 + <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  15 + <uses-permission android:name="android.permission.BLUETOOTH"/>
  16 + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
  17 + <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
  18 +
13 <uses-permission android:name="android.permission.INTERNET" /> 19 <uses-permission android:name="android.permission.INTERNET" />
14 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 20 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
15 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 21 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -36,6 +42,13 @@ @@ -36,6 +42,13 @@
36 <uses-permission android:name="android.permission.READ_CALL_LOG" /> 42 <uses-permission android:name="android.permission.READ_CALL_LOG" />
37 43
38 44
  45 + <queries>
  46 + <intent>
  47 + <action android:name="android.speech.RecognitionService" />
  48 + </intent>
  49 + </queries>
  50 +
  51 +
39 52
40 53
41 <application 54 <application
@@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1536M @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1536M
3 # android.enableR8=true 3 # android.enableR8=true
4 android.useAndroidX=true 4 android.useAndroidX=true
5 android.enableJetifier=true 5 android.enableJetifier=true
6 -android.suppressUnsupportedCompileSdk = 34 6 +android.suppressUnsupportedCompileSdk=34,35
7 org.gradle.warning.mode=all 7 org.gradle.warning.mode=all
8 8
9 # android.jetifier.blacklist=bcprov-jdk15on 9 # android.jetifier.blacklist=bcprov-jdk15on
1 -import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart'; 1 +// import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart';
2 2
3 -class ConstConfig {  
4 - static const AMapApiKey amapApiKeys = AMapApiKey(  
5 - androidKey: '900f72eeee0f21e435cebb0ef155582a', //测试key  
6 - iosKey: '4dfdec97b7bf0b8c13e94777103015a9', //测试key  
7 - ohosKey: '7c2081e92ec65bfffa2df0a5464f0c7b'); //我的账户下面的ceshikey  
8 - static const AMapPrivacyStatement amapPrivacyStatement =  
9 - AMapPrivacyStatement(hasContains: true, hasShow: true, hasAgree: true);  
10 -} 3 +// class ConstConfig {
  4 +// static const AMapApiKey amapApiKeys = AMapApiKey(
  5 +// androidKey: '900f72eeee0f21e435cebb0ef155582a', //测试key
  6 +// iosKey: '4dfdec97b7bf0b8c13e94777103015a9', //测试key
  7 +// ohosKey: '7c2081e92ec65bfffa2df0a5464f0c7b'); //我的账户下面的ceshikey
  8 +// static const AMapPrivacyStatement amapPrivacyStatement =
  9 +// AMapPrivacyStatement(hasContains: true, hasShow: true, hasAgree: true);
  10 +// }
1 -// import 'dart:async';  
2 -  
3 -// import 'package:amap_map_fluttify/amap_map_fluttify.dart';  
4 -// import 'package:flutter/cupertino.dart';  
5 -  
6 -// import 'package:flutter/material.dart';  
7 -  
8 -// import 'package:flutter_easyrefresh/easy_refresh.dart';  
9 -  
10 -  
11 -// import 'package:one_key/res/colors.dart';  
12 -  
13 -// import 'package:one_key/utils/misc.dart';  
14 -  
15 -// import 'package:one_key/utils/screen_util.dart';  
16 -// import 'package:one_key/utils/utils.dart';  
17 -  
18 -// import 'package:one_key/widgets/system_app_bar.dart';  
19 -// import 'package:permission_handler/permission_handler.dart';  
20 -  
21 -// import '../../utils/common_utils.dart';  
22 -// // import 'package:demo/resources/custom_text_style.dart';  
23 -// // import 'package:demo/utils/misc.dart';  
24 -  
25 -// // import 'package:demo/widgets/network_state/page_loading.dart';  
26 -  
27 -// class MapChoicePointPage extends StatefulWidget {  
28 -// final String? long;  
29 -// final String? lat;  
30 -// MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);  
31 -  
32 -// @override  
33 -// _MapChoicePointPageState createState() => _MapChoicePointPageState();  
34 -// }  
35 -  
36 -// class _MapChoicePointPageState extends State<MapChoicePointPage> {  
37 -// AmapController? _controller;  
38 -// List<Poi>? poiList;  
39 -// static List<PoiModel?> list = [];  
40 -// static List<PoiModel> searchlist = [];  
41 -// PoiModel? poiModel;  
42 -// String keyword = "";  
43 -// String? address = "";  
44 -// bool isloading = true;  
45 -  
46 -// double latitude = 39.684670899;  
47 -// double longitude = 118.17630045;  
48 -  
49 -// double latitudeLocation = 39.684670899;  
50 -// double longitudeLocation = 118.17630045;  
51 -  
52 -// List<InputTip> inputTipDatas = [];  
53 -// int page = 1;  
54 -// EasyRefreshController refreshController = EasyRefreshController();  
55 -// bool flag = true;  
56 -  
57 -// @override  
58 -// void initState() {  
59 -// super.initState();  
60 -  
61 -// if (widget.long != null && widget.long != '' && widget.long != 'null') {  
62 -// longitude = double.parse(widget.long!);  
63 -// }  
64 -// if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {  
65 -// latitude = double.parse(widget.lat!);  
66 -// }  
67 -  
68 -// WidgetsBinding.instance.addPostFrameCallback((_) async {  
69 -// _requestLocationPermission();  
70 -  
71 -// // ama  
72 -// // let marker = new AMap.Marker({//添加标记点  
73 -// // position: this.position,  
74 -// // map: map  
75 -// });  
76 -// }  
77 -  
78 -// // Future<bool> checkLocationPermission() async {  
79 -// // PermissionStatus permissionStatus = await Permission.location.status;  
80 -// // if (permissionStatus == PermissionStatus.granted) {  
81 -// // return true;  
82 -// // } else {  
83 -// // return false;  
84 -// // }  
85 -// // }  
86 -  
87 -// /// 检查权限并定  
88 -// // _getLocationPermission() async {  
89 -// // if (!(await checkPermission(Permission.location))) {  
90 -// // //没有定位权限  
91 -  
92 -// // //申请定位权限  
93 -// // _requestLocationPermission();  
94 -// // } else {  
95 -// // //去定位  
96 -// // _requestLocationPermission();  
97 -// // }  
98 -// // }  
99 -  
100 -// /// 获取定位权限  
101 -// _requestLocationPermission() async {  
102 -// await AmapLocation.instance.updatePrivacyShow(true);  
103 -// await AmapLocation.instance.updatePrivacyAgree(true);  
104 -// bool canLocation = false;  
105 -  
106 -// if (!(await checkPermission(Permission.location))) {  
107 -// //没有定位权限  
108 -  
109 -// //申请定位权限  
110 -// canLocation = await requestPermission(Permission.location);  
111 -// } else {  
112 -// canLocation = true;  
113 -// }  
114 -// // bool canLocation = await requestPermission(Permission.location);  
115 -// // 单次定位  
116 -// if (canLocation) {  
117 -// Future.delayed(Duration(milliseconds: 200), () async {  
118 -// await AmapLocation.instance.updatePrivacyShow(true);  
119 -// await AmapLocation.instance.updatePrivacyAgree(true);  
120 -// final location = await AmapLocation.instance.fetchLocation(  
121 -// // needAddress: true,  
122 -// // mode: LocationAccuracy.High,  
123 -// // timeout: Duration(seconds: 10)  
124 -// );  
125 -  
126 -// if (location.city == null || location.city == '') //网络不好,定位失败  
127 -// {  
128 -// // App.sp.setString("lat", "39.684670899");  
129 -// // App.sp.setString("lng", "118.17630045");  
130 -// } else {  
131 -// if (widget.long == null ||  
132 -// widget.long == '' ||  
133 -// widget.long == 'null') {  
134 -// latitude = location.latLng!.latitude;  
135 -// longitude = location.latLng!.longitude;  
136 -// if (_controller != null) {  
137 -// _controller!.setCenterCoordinate(LatLng(  
138 -// location.latLng!.latitude, location.latLng!.longitude));  
139 -// }  
140 -  
141 -// page = 1;  
142 -  
143 -// _loadData(  
144 -// LatLng(location.latLng!.latitude, location.latLng!.longitude));  
145 -  
146 -// setState(() {});  
147 -// }  
148 -// latitudeLocation = location.latLng!.latitude;  
149 -// longitudeLocation = location.latLng!.longitude;  
150 -// }  
151 -// });  
152 -// } else {  
153 -// //无权限  
154 -// }  
155 -// }  
156 -  
157 -// @override  
158 -// Widget build(BuildContext context) {  
159 -// return Scaffold(  
160 -// resizeToAvoidBottomInset: false, //防止底部布局被顶起  
161 -// appBar: SystemAppBar(  
162 -// '选择位置信息',  
163 -// onTap: () {  
164 -// if (Navigator.canPop(context)) {  
165 -// Navigator.pop(context);  
166 -// }  
167 -// },  
168 -// ),  
169 -  
170 -// body: Column(  
171 -// children: <Widget>[  
172 -// // Theme(  
173 -// // data: new  
174 -// // ThemeData(  
175 -// // // primaryColor: MyColours.color_438E93,  
176 -// // // hintColor: MyColours.color_438E93),  
177 -// // child:  
178 -// // Container(  
179 -// // color: MyColours.color_438E93,  
180 -// // decoration: BoxDecoration(  
181 -// // color: MyColours.color_438E93,  
182 -// // boxShadow: [  
183 -// // BoxShadow(color: Colors.white, spreadRadius: 1),  
184 -// // ],  
185 -// // ),  
186 -  
187 -// // padding: EdgeInsets.all(5),  
188 -// // child:  
189 -  
190 -// // ),  
191 -// // ),  
192 -// // ListView.builder(  
193 -// // shrinkWrap: true,  
194 -// // itemCount: inputTipDatas.length,  
195 -// // itemBuilder: (context, index) {  
196 -// // InputTip inputTip = inputTipDatas[index];  
197 -// // return InkWell(  
198 -// // onTap: () {  
199 -// // // searchAroundAddress(inputTip.name ?? '');  
200 -// // // searchPoiId(inputTip.poiId ?? '');  
201 -// // // _loadData(inputTip.coordinate ??  
202 -// // // LatLng(latitude, longitude));  
203 -// // },  
204 -// // child: Container(  
205 -// // child: Row(  
206 -// // children: [  
207 -// // Text(  
208 -// // inputTip.name ?? '',  
209 -// // style: TextStyle(  
210 -// // fontSize: font(15),  
211 -// // color: MyColours.color_515151),  
212 -// // ),  
213 -// // HEmptyView(10),  
214 -// // Expanded(  
215 -// // child: Text(  
216 -// // (inputTip.district ?? '') +  
217 -// // (inputTip.address ?? ''),  
218 -// // style: TextStyle(  
219 -// // fontSize: font(13),  
220 -// // color: MyColours.color_999999),  
221 -// // ),  
222 -// // ),  
223 -// // ],  
224 -// // )));  
225 -// // })  
226 -// // ],  
227 -// // ),  
228 -  
229 -// Stack(  
230 -// children: [  
231 -// Container(  
232 -// height: w(300),  
233 -// child: Stack(  
234 -// children: <Widget>[  
235 -// AmapView(  
236 -// showZoomControl: false,  
237 -  
238 -// /// 是否显示指南针控件  
239 -// showCompass: true,  
240 -  
241 -// /// 是否显示比例尺控件  
242 -// showScaleControl: true,  
243 -  
244 -// /// 是否使能缩放手势  
245 -// zoomGesturesEnabled: true,  
246 -  
247 -// /// 是否使能滚动手势  
248 -// scrollGesturesEnabled: true,  
249 -  
250 -// /// 是否使能旋转手势  
251 -// rotateGestureEnabled: false,  
252 -// centerCoordinate: LatLng(latitude, longitude),  
253 -// maskDelay: Duration(milliseconds: 500),  
254 -// zoomLevel: 19,  
255 -// onMapCreated: (controller) async {  
256 -// _controller = controller;  
257 -// _controller!  
258 -// .setCenterCoordinate(LatLng(latitude, longitude));  
259 -// // if (await requestPermission(PermissionGroup.location)) {  
260 -// // await controller.showMyLocation(true);  
261 -// // await controller?.showLocateControl(true);  
262 -// // final latLng = await _controller?.getLocation(  
263 -// // delay: Duration(seconds: 2));  
264 -// // await enableFluttifyLog(false); // 关闭log  
265 -// // _loadData(latLng);  
266 -// // } else {  
267 -// // //无权限  
268 -// // _showLocPemWidget();  
269 -// // }  
270 -// },  
271 -// // markers: [],  
272 -// onMapMoveEnd: (MapMove move) async {  
273 -// latitude = move.coordinate!.latitude;  
274 -// longitude = move.coordinate!.longitude;  
275 -// page = 1;  
276 -// _loadData(move.coordinate!);  
277 -// },  
278 -// ),  
279 -// Center(  
280 -// child: Icon(  
281 -// Icons.place,  
282 -// size: w(32),  
283 -// color: Color(0xFFFF0000),  
284 -// ),  
285 -// ),  
286 -// Positioned(  
287 -// right: w(10),  
288 -// bottom: w(10),  
289 -// child: InkWell(  
290 -// onTap: () {  
291 -// _controller!.setCenterCoordinate(  
292 -// LatLng(latitudeLocation, longitudeLocation));  
293 -// },  
294 -// child: Container(  
295 -// decoration: BoxDecoration(  
296 -// color: MyColours.color_ffffff,  
297 -// borderRadius: BorderRadius.circular(r(5))),  
298 -// padding: EdgeInsets.all(w(5)),  
299 -// child: Image.asset(  
300 -// Utils.getImgPath('location_map'),  
301 -// width: w(25),  
302 -// ),  
303 -// )),  
304 -// )  
305 -// ],  
306 -// ),  
307 -// ),  
308 -// Positioned(  
309 -// top: w(10),  
310 -// left: w(20),  
311 -// right: w(20),  
312 -// child: Container(  
313 -// // height: w(45),  
314 -// padding: EdgeInsets.symmetric(vertical: w(10)),  
315 -// decoration: BoxDecoration(  
316 -// color: Colors.white,  
317 -// borderRadius: BorderRadius.circular(r(10))),  
318 -// child: TextField(  
319 -// textAlignVertical: TextAlignVertical.center,  
320 -// style: TextStyle(  
321 -// color: MyColours.color_515151,  
322 -// fontSize: font(15),  
323 -// ),  
324 -// controller:  
325 -// TextEditingController.fromValue(TextEditingValue(  
326 -// // 设置内容  
327 -// text: keyword,  
328 -// selection: TextSelection.fromPosition(TextPosition(  
329 -// affinity: TextAffinity.downstream,  
330 -// offset: keyword.length)),  
331 -// // 保持光标在最后  
332 -// )),  
333 -// decoration: InputDecoration(  
334 -// // border: b,  
335 -// // border: OutlineInputBorder(  
336 -// // borderRadius: BorderRadius.all(Radius.circular(40)),  
337 -// // ),  
338 -// border: OutlineInputBorder(borderSide: BorderSide.none),  
339 -// hintText: '输入关键字',  
340 -// isCollapsed: true,  
341 -  
342 -// hintStyle: TextStyle(  
343 -// color: MyColours.color_999999, fontSize: font(15)),  
344 -// // contentPadding: const EdgeInsets.symmetric(  
345 -// // vertical: 8, horizontal: 1),  
346 -// prefixIconConstraints: BoxConstraints(maxWidth: w(40)),  
347 -// prefixIcon: Padding(  
348 -// padding: EdgeInsets.only(left: w(10), right: w(10)),  
349 -// child: SizedBox(  
350 -// width: w(30),  
351 -// child: Image.asset(  
352 -// Utils.getImgPath('search_black'),  
353 -// ))),  
354 -// suffixIconConstraints: BoxConstraints(maxWidth: w(32)),  
355 -// suffixIcon: InkWell(  
356 -// child: Padding(  
357 -// padding: EdgeInsets.only(left: w(10), right: w(10)),  
358 -// child: SizedBox(  
359 -// width: w(22),  
360 -// child: Image.asset(  
361 -// Utils.getImgPath('delete_black'),  
362 -// ))),  
363 -// onTap: () {  
364 -// keyword = "";  
365 -// setState(() {});  
366 -// },  
367 -// ),  
368 -// fillColor: Colors.white,  
369 -// filled: true,  
370 -// ),  
371 -  
372 -// inputFormatters: [],  
373 -// //内容改变的回调  
374 -// onChanged: (text) {  
375 -// print('change $text');  
376 -// keyword = text;  
377 -  
378 -// //搜索  
379 -  
380 -// JhCommonUtils.debounce(  
381 -// () => _fetchInputTips(text.toString()));  
382 -// },  
383 -// //内容提交(按回车)的回调  
384 -// onSubmitted: (text) {  
385 -// print('submit $text');  
386 -// // 触发关闭弹出来的键盘。  
387 -// keyword = text;  
388 -// FocusScope.of(context).requestFocus(FocusNode());  
389 -// setState(() {  
390 -// // isloading = true;  
391 -// });  
392 -  
393 -// // _fetchInputTips(text.toString());  
394 -  
395 -// // searchAroundAddress(text.toString());  
396 -// },  
397 -// //按回车时调用  
398 -// onEditingComplete: () {  
399 -// print('onEditingComplete');  
400 -// },  
401 -// ),  
402 -// ),  
403 -// )  
404 -// ],  
405 -// ),  
406 -  
407 -// Expanded(  
408 -// flex: 1,  
409 -// child: Visibility(  
410 -// visible: !isloading,  
411 -// maintainSize: false,  
412 -// maintainSemantics: false,  
413 -// maintainInteractivity: false,  
414 -// replacement: Center(  
415 -// child: CupertinoActivityIndicator(),  
416 -// ),  
417 -// child: EasyRefresh.custom(  
418 -// controller: refreshController,  
419 -// slivers: [  
420 -// SliverList(  
421 -// delegate: SliverChildBuilderDelegate(  
422 -// (BuildContext context, int position) {  
423 -// print("itemBuilder" + list.length.toString());  
424 -// PoiModel item = list[position]!;  
425 -// return InkWell(  
426 -// child: Column(  
427 -// children: <Widget>[  
428 -// Container(  
429 -// margin: EdgeInsets.only(  
430 -// top: 8, bottom: 5, left: 10),  
431 -// child: Row(  
432 -// children: <Widget>[  
433 -// Icon(  
434 -// Icons.place,  
435 -// size: 20.0,  
436 -// color: position == 0  
437 -// ? Colors.green  
438 -// : Colors.grey,  
439 -// ),  
440 -// Expanded(  
441 -// child: Text(item.title,  
442 -// style: TextStyle(  
443 -// fontSize: 16,  
444 -// color: position == 0  
445 -// ? Colors.green  
446 -// : Color(0xFF787878))))  
447 -// ],  
448 -// ),  
449 -// ),  
450 -// Container(  
451 -// margin: EdgeInsets.only(  
452 -// top: 5, bottom: 5, left: 18),  
453 -// alignment: Alignment.centerLeft,  
454 -// child: Text(  
455 -// item.address!,  
456 -// style: TextStyle(  
457 -// fontSize: 14,  
458 -// color: Color(0xFF646464),  
459 -// ),  
460 -// ),  
461 -// ),  
462 -// Divider(  
463 -// height: 1,  
464 -// )  
465 -// ],  
466 -// ),  
467 -// onTap: () async {  
468 -// // await _controller.setCenterCoordinate(  
469 -// // LatLng(item.latLng.latitude, item.latLng.longitude),  
470 -// // zoomLevel: 16);  
471 -// if (Navigator.canPop(context)) {  
472 -// Navigator.pop(context, {  
473 -// 'address': item.address,  
474 -// 'lat': item.latLng!.latitude.toString(),  
475 -// 'lng': item.latLng!.longitude.toString()  
476 -// });  
477 -// }  
478 -// },  
479 -// );  
480 -// },  
481 -// childCount: list.length,  
482 -// ),  
483 -// )  
484 -// ],  
485 -// onRefresh: () async {  
486 -// if (flag) {  
487 -// page = 1;  
488 -// _loadData(LatLng(latitude, longitude));  
489 -// }  
490 -// },  
491 -// onLoad: () async {  
492 -// if (flag) {  
493 -// page++;  
494 -// _loadData(LatLng(latitude, longitude),  
495 -// showloading: false);  
496 -// }  
497 -// },  
498 -// )),  
499 -// ),  
500 -// ],  
501 -// ),  
502 -// );  
503 -// }  
504 -  
505 -// _fetchInputTips(String text) async {  
506 -// flag = false;  
507 -// page = 1;  
508 -// // setState(() {  
509 -// // isloading = true;  
510 -// // });  
511 -  
512 -// /// 逆地理编码(坐标转地址)  
513 -// ///  
514 -// ///  
515 -// await AmapLocation.instance.updatePrivacyShow(true);  
516 -// await AmapLocation.instance.updatePrivacyAgree(true);  
517 -  
518 -// LatLng latLng = LatLng(latitude, longitude);  
519 -// ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(latLng);  
520 -  
521 -// // print(await reGeocodeList.toFutureString());  
522 -// address = reGeocodeList.formatAddress;  
523 -  
524 -// await AmapLocation.instance.updatePrivacyShow(true);  
525 -// await AmapLocation.instance.updatePrivacyAgree(true);  
526 -// inputTipDatas = await AmapSearch.instance.fetchInputTips(  
527 -// text,  
528 -// city: "",  
529 -// );  
530 -// print(inputTipDatas);  
531 -  
532 -// poiModel = new PoiModel("当前位置", address, latLng);  
533 -// list.clear();  
534 -// list.add(poiModel);  
535 -// for (var inputTip in inputTipDatas) {  
536 -// String? title = await inputTip.name ?? '';  
537 -// String? cityStr =  
538 -// await (inputTip.district ?? '') + (inputTip.address ?? '');  
539 -  
540 -// LatLng? latLng = await inputTip.coordinate;  
541 -  
542 -// list.add(new PoiModel(title.toString(), cityStr, latLng));  
543 -// }  
544 -  
545 -  
546 -// print(list);  
547 -  
548 -// setState(() {  
549 -// // isloading = false;  
550 -// });  
551 -// }  
552 -  
553 -// void _loadData(LatLng latLng, {showloading = true}) async {  
554 -// flag = true;  
555 -// setState(() {  
556 -// if (showloading) {  
557 -// isloading = true;  
558 -// }  
559 -// });  
560 -  
561 -// /// 逆地理编码(坐标转地址)  
562 -// ///  
563 -// ///  
564 -  
565 -// await AmapLocation.instance.updatePrivacyShow(true);  
566 -// await AmapLocation.instance.updatePrivacyAgree(true);  
567 -// if (page == 1) {  
568 -// ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(  
569 -// latLng,  
570 -// );  
571 -// // print(await reGeocodeList.toFutureString());  
572 -// address = reGeocodeList.formatAddress;  
573 -// poiModel = new PoiModel("当前位置", address, latLng);  
574 -// list.clear();  
575 -// list.add(poiModel);  
576 -// }  
577 -// final poiList =  
578 -// await AmapSearch.instance.searchAround(latLng, city: "", page: page);  
579 -  
580 -// for (var poi in poiList) {  
581 -// String? title = await poi.title;  
582 -// String? cityName = await poi.cityName;  
583 -// String? provinceName = await poi.provinceName;  
584 -// String? address = await poi.address;  
585 -// LatLng? latLng = await poi.latLng;  
586 -// String? bussniss = poi.businessArea;  
587 -  
588 -// list.add(new PoiModel(  
589 -// title.toString(),  
590 -// provinceName.toString() +  
591 -// cityName.toString() +  
592 -// address.toString() +  
593 -// bussniss.toString(),  
594 -// latLng));  
595 -// }  
596 -  
597 -// setState(() {  
598 -// if (showloading) {  
599 -// isloading = false;  
600 -// }  
601 -// });  
602 -// }  
603 -  
604 -// // void searchPoiId(String text) async {  
605 -// // await AmapLocation.instance.updatePrivacyShow(true);  
606 -// // await AmapLocation.instance.updatePrivacyAgree(true);  
607 -// // Poi? poi = await AmapSearch.instance.searchPoiId(  
608 -// // text,  
609 -// // );  
610 -// // print(poi);  
611 -// // }  
612 -  
613 -// // void searchAroundAddress(String text) async {  
614 -// // await AmapLocation.instance.updatePrivacyShow(true);  
615 -// // await AmapLocation.instance.updatePrivacyAgree(true);  
616 -// // final poiList = await AmapSearch.instance.searchKeyword(  
617 -// // text,  
618 -// // city: "",  
619 -// // );  
620 -// // // final poiList = await AmapSearch.instance.searchAround(  
621 -// // // LatLng(latitude, longitude),  
622 -// // // city: "",  
623 -// // // radius: 100000000000000  
624 -  
625 -// // // );  
626 -  
627 -// // list.clear();  
628 -// // list.add(poiModel);  
629 -// // for (var poi in poiList) {  
630 -// // String? title = await poi.title;  
631 -// // LatLng? latLng = await poi.latLng;  
632 -// // String? cityName = await poi.cityName;  
633 -// // String? provinceName = await poi.provinceName;  
634 -// // String? address = await poi.address;  
635 -// // list.add(new PoiModel(  
636 -// // title.toString(),  
637 -// // provinceName.toString() + cityName.toString() + address.toString(),  
638 -// // latLng));  
639 -// // }  
640 -// // setState(() {  
641 -// // isloading = false;  
642 -// // FocusScope.of(context).requestFocus(FocusNode());  
643 -// // });  
644 -// // }  
645 -// }  
646 -  
647 -// class PoiModel {  
648 -// LatLng? latLng;  
649 -// String title;  
650 -// String? address;  
651 -  
652 -// PoiModel(this.title, this.address, this.latLng);  
653 -// } 1 +import 'dart:async';
  2 +
  3 +import 'package:amap_map_fluttify/amap_map_fluttify.dart';
  4 +import 'package:flutter/cupertino.dart';
  5 +
  6 +import 'package:flutter/material.dart';
  7 +
  8 +import 'package:flutter_easyrefresh/easy_refresh.dart';
  9 +
  10 +
  11 +import 'package:one_key/res/colors.dart';
  12 +
  13 +import 'package:one_key/utils/misc.dart';
  14 +
  15 +import 'package:one_key/utils/screen_util.dart';
  16 +import 'package:one_key/utils/utils.dart';
  17 +
  18 +import 'package:one_key/widgets/system_app_bar.dart';
  19 +import 'package:permission_handler/permission_handler.dart';
  20 +
  21 +import '../../utils/common_utils.dart';
  22 +// import 'package:demo/resources/custom_text_style.dart';
  23 +// import 'package:demo/utils/misc.dart';
  24 +
  25 +// import 'package:demo/widgets/network_state/page_loading.dart';
  26 +
  27 +class MapChoicePointPage extends StatefulWidget {
  28 + final String? long;
  29 + final String? lat;
  30 + MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);
  31 +
  32 + @override
  33 + _MapChoicePointPageState createState() => _MapChoicePointPageState();
  34 +}
  35 +
  36 +class _MapChoicePointPageState extends State<MapChoicePointPage> {
  37 + AmapController? _controller;
  38 + List<Poi>? poiList;
  39 + static List<PoiModel?> list = [];
  40 + static List<PoiModel> searchlist = [];
  41 + PoiModel? poiModel;
  42 + String keyword = "";
  43 + String? address = "";
  44 + bool isloading = true;
  45 +
  46 + double latitude = 39.684670899;
  47 + double longitude = 118.17630045;
  48 +
  49 + double latitudeLocation = 39.684670899;
  50 + double longitudeLocation = 118.17630045;
  51 +
  52 + List<InputTip> inputTipDatas = [];
  53 + int page = 1;
  54 + EasyRefreshController refreshController = EasyRefreshController();
  55 + bool flag = true;
  56 +
  57 + @override
  58 + void initState() {
  59 + super.initState();
  60 +
  61 + if (widget.long != null && widget.long != '' && widget.long != 'null') {
  62 + longitude = double.parse(widget.long!);
  63 + }
  64 + if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {
  65 + latitude = double.parse(widget.lat!);
  66 + }
  67 +
  68 + WidgetsBinding.instance.addPostFrameCallback((_) async {
  69 + _requestLocationPermission();
  70 +
  71 + // ama
  72 + // let marker = new AMap.Marker({//添加标记点
  73 + // position: this.position,
  74 + // map: map
  75 + });
  76 + }
  77 +
  78 + // Future<bool> checkLocationPermission() async {
  79 + // PermissionStatus permissionStatus = await Permission.location.status;
  80 + // if (permissionStatus == PermissionStatus.granted) {
  81 + // return true;
  82 + // } else {
  83 + // return false;
  84 + // }
  85 + // }
  86 +
  87 + /// 检查权限并定
  88 + // _getLocationPermission() async {
  89 + // if (!(await checkPermission(Permission.location))) {
  90 + // //没有定位权限
  91 +
  92 + // //申请定位权限
  93 + // _requestLocationPermission();
  94 + // } else {
  95 + // //去定位
  96 + // _requestLocationPermission();
  97 + // }
  98 + // }
  99 +
  100 + /// 获取定位权限
  101 + _requestLocationPermission() async {
  102 + await AmapLocation.instance.updatePrivacyShow(true);
  103 + await AmapLocation.instance.updatePrivacyAgree(true);
  104 + bool canLocation = false;
  105 +
  106 + if (!(await checkPermission(Permission.location))) {
  107 + //没有定位权限
  108 +
  109 + //申请定位权限
  110 + canLocation = await requestPermission(Permission.location);
  111 + } else {
  112 + canLocation = true;
  113 + }
  114 + // bool canLocation = await requestPermission(Permission.location);
  115 + // 单次定位
  116 + if (canLocation) {
  117 + Future.delayed(Duration(milliseconds: 200), () async {
  118 + await AmapLocation.instance.updatePrivacyShow(true);
  119 + await AmapLocation.instance.updatePrivacyAgree(true);
  120 + final location = await AmapLocation.instance.fetchLocation(
  121 + // needAddress: true,
  122 + // mode: LocationAccuracy.High,
  123 + // timeout: Duration(seconds: 10)
  124 + );
  125 +
  126 + if (location.city == null || location.city == '') //网络不好,定位失败
  127 + {
  128 + // App.sp.setString("lat", "39.684670899");
  129 + // App.sp.setString("lng", "118.17630045");
  130 + } else {
  131 + if (widget.long == null ||
  132 + widget.long == '' ||
  133 + widget.long == 'null') {
  134 + latitude = location.latLng!.latitude;
  135 + longitude = location.latLng!.longitude;
  136 + if (_controller != null) {
  137 + _controller!.setCenterCoordinate(LatLng(
  138 + location.latLng!.latitude, location.latLng!.longitude));
  139 + }
  140 +
  141 + page = 1;
  142 +
  143 + _loadData(
  144 + LatLng(location.latLng!.latitude, location.latLng!.longitude));
  145 +
  146 + setState(() {});
  147 + }
  148 + latitudeLocation = location.latLng!.latitude;
  149 + longitudeLocation = location.latLng!.longitude;
  150 + }
  151 + });
  152 + } else {
  153 + //无权限
  154 + }
  155 + }
  156 +
  157 + @override
  158 + Widget build(BuildContext context) {
  159 + return Scaffold(
  160 + resizeToAvoidBottomInset: false, //防止底部布局被顶起
  161 + appBar: SystemAppBar(
  162 + '选择位置信息',
  163 + onTap: () {
  164 + if (Navigator.canPop(context)) {
  165 + Navigator.pop(context);
  166 + }
  167 + },
  168 + ),
  169 +
  170 + body: Column(
  171 + children: <Widget>[
  172 + // Theme(
  173 + // data: new
  174 + // ThemeData(
  175 + // // primaryColor: MyColours.color_438E93,
  176 + // // hintColor: MyColours.color_438E93),
  177 + // child:
  178 + // Container(
  179 + // color: MyColours.color_438E93,
  180 + // decoration: BoxDecoration(
  181 + // color: MyColours.color_438E93,
  182 + // boxShadow: [
  183 + // BoxShadow(color: Colors.white, spreadRadius: 1),
  184 + // ],
  185 + // ),
  186 +
  187 + // padding: EdgeInsets.all(5),
  188 + // child:
  189 +
  190 + // ),
  191 + // ),
  192 + // ListView.builder(
  193 + // shrinkWrap: true,
  194 + // itemCount: inputTipDatas.length,
  195 + // itemBuilder: (context, index) {
  196 + // InputTip inputTip = inputTipDatas[index];
  197 + // return InkWell(
  198 + // onTap: () {
  199 + // // searchAroundAddress(inputTip.name ?? '');
  200 + // // searchPoiId(inputTip.poiId ?? '');
  201 + // // _loadData(inputTip.coordinate ??
  202 + // // LatLng(latitude, longitude));
  203 + // },
  204 + // child: Container(
  205 + // child: Row(
  206 + // children: [
  207 + // Text(
  208 + // inputTip.name ?? '',
  209 + // style: TextStyle(
  210 + // fontSize: font(15),
  211 + // color: MyColours.color_515151),
  212 + // ),
  213 + // HEmptyView(10),
  214 + // Expanded(
  215 + // child: Text(
  216 + // (inputTip.district ?? '') +
  217 + // (inputTip.address ?? ''),
  218 + // style: TextStyle(
  219 + // fontSize: font(13),
  220 + // color: MyColours.color_999999),
  221 + // ),
  222 + // ),
  223 + // ],
  224 + // )));
  225 + // })
  226 + // ],
  227 + // ),
  228 +
  229 + Stack(
  230 + children: [
  231 + Container(
  232 + height: w(300),
  233 + child: Stack(
  234 + children: <Widget>[
  235 + AmapView(
  236 + showZoomControl: false,
  237 +
  238 + /// 是否显示指南针控件
  239 + showCompass: true,
  240 +
  241 + /// 是否显示比例尺控件
  242 + showScaleControl: true,
  243 +
  244 + /// 是否使能缩放手势
  245 + zoomGesturesEnabled: true,
  246 +
  247 + /// 是否使能滚动手势
  248 + scrollGesturesEnabled: true,
  249 +
  250 + /// 是否使能旋转手势
  251 + rotateGestureEnabled: false,
  252 + centerCoordinate: LatLng(latitude, longitude),
  253 + maskDelay: Duration(milliseconds: 500),
  254 + zoomLevel: 19,
  255 + onMapCreated: (controller) async {
  256 + _controller = controller;
  257 + _controller!
  258 + .setCenterCoordinate(LatLng(latitude, longitude));
  259 + // if (await requestPermission(PermissionGroup.location)) {
  260 + // await controller.showMyLocation(true);
  261 + // await controller?.showLocateControl(true);
  262 + // final latLng = await _controller?.getLocation(
  263 + // delay: Duration(seconds: 2));
  264 + // await enableFluttifyLog(false); // 关闭log
  265 + // _loadData(latLng);
  266 + // } else {
  267 + // //无权限
  268 + // _showLocPemWidget();
  269 + // }
  270 + },
  271 + // markers: [],
  272 + onMapMoveEnd: (MapMove move) async {
  273 + latitude = move.coordinate!.latitude;
  274 + longitude = move.coordinate!.longitude;
  275 + page = 1;
  276 + _loadData(move.coordinate!);
  277 + },
  278 + ),
  279 + Center(
  280 + child: Icon(
  281 + Icons.place,
  282 + size: w(32),
  283 + color: Color(0xFFFF0000),
  284 + ),
  285 + ),
  286 + Positioned(
  287 + right: w(10),
  288 + bottom: w(10),
  289 + child: InkWell(
  290 + onTap: () {
  291 + _controller!.setCenterCoordinate(
  292 + LatLng(latitudeLocation, longitudeLocation));
  293 + },
  294 + child: Container(
  295 + decoration: BoxDecoration(
  296 + color: MyColours.color_ffffff,
  297 + borderRadius: BorderRadius.circular(r(5))),
  298 + padding: EdgeInsets.all(w(5)),
  299 + child: Image.asset(
  300 + Utils.getImgPath('location_map'),
  301 + width: w(25),
  302 + ),
  303 + )),
  304 + )
  305 + ],
  306 + ),
  307 + ),
  308 + Positioned(
  309 + top: w(10),
  310 + left: w(20),
  311 + right: w(20),
  312 + child: Container(
  313 + // height: w(45),
  314 + padding: EdgeInsets.symmetric(vertical: w(10)),
  315 + decoration: BoxDecoration(
  316 + color: Colors.white,
  317 + borderRadius: BorderRadius.circular(r(10))),
  318 + child: TextField(
  319 + textAlignVertical: TextAlignVertical.center,
  320 + style: TextStyle(
  321 + color: MyColours.color_515151,
  322 + fontSize: font(15),
  323 + ),
  324 + controller:
  325 + TextEditingController.fromValue(TextEditingValue(
  326 + // 设置内容
  327 + text: keyword,
  328 + selection: TextSelection.fromPosition(TextPosition(
  329 + affinity: TextAffinity.downstream,
  330 + offset: keyword.length)),
  331 + // 保持光标在最后
  332 + )),
  333 + decoration: InputDecoration(
  334 + // border: b,
  335 + // border: OutlineInputBorder(
  336 + // borderRadius: BorderRadius.all(Radius.circular(40)),
  337 + // ),
  338 + border: OutlineInputBorder(borderSide: BorderSide.none),
  339 + hintText: '输入关键字',
  340 + isCollapsed: true,
  341 +
  342 + hintStyle: TextStyle(
  343 + color: MyColours.color_999999, fontSize: font(15)),
  344 + // contentPadding: const EdgeInsets.symmetric(
  345 + // vertical: 8, horizontal: 1),
  346 + prefixIconConstraints: BoxConstraints(maxWidth: w(40)),
  347 + prefixIcon: Padding(
  348 + padding: EdgeInsets.only(left: w(10), right: w(10)),
  349 + child: SizedBox(
  350 + width: w(30),
  351 + child: Image.asset(
  352 + Utils.getImgPath('search_black'),
  353 + ))),
  354 + suffixIconConstraints: BoxConstraints(maxWidth: w(32)),
  355 + suffixIcon: InkWell(
  356 + child: Padding(
  357 + padding: EdgeInsets.only(left: w(10), right: w(10)),
  358 + child: SizedBox(
  359 + width: w(22),
  360 + child: Image.asset(
  361 + Utils.getImgPath('delete_black'),
  362 + ))),
  363 + onTap: () {
  364 + keyword = "";
  365 + setState(() {});
  366 + },
  367 + ),
  368 + fillColor: Colors.white,
  369 + filled: true,
  370 + ),
  371 +
  372 + inputFormatters: [],
  373 + //内容改变的回调
  374 + onChanged: (text) {
  375 + print('change $text');
  376 + keyword = text;
  377 +
  378 + //搜索
  379 +
  380 + JhCommonUtils.debounce(
  381 + () => _fetchInputTips(text.toString()));
  382 + },
  383 + //内容提交(按回车)的回调
  384 + onSubmitted: (text) {
  385 + print('submit $text');
  386 + // 触发关闭弹出来的键盘。
  387 + keyword = text;
  388 + FocusScope.of(context).requestFocus(FocusNode());
  389 + setState(() {
  390 + // isloading = true;
  391 + });
  392 +
  393 + // _fetchInputTips(text.toString());
  394 +
  395 + // searchAroundAddress(text.toString());
  396 + },
  397 + //按回车时调用
  398 + onEditingComplete: () {
  399 + print('onEditingComplete');
  400 + },
  401 + ),
  402 + ),
  403 + )
  404 + ],
  405 + ),
  406 +
  407 + Expanded(
  408 + flex: 1,
  409 + child: Visibility(
  410 + visible: !isloading,
  411 + maintainSize: false,
  412 + maintainSemantics: false,
  413 + maintainInteractivity: false,
  414 + replacement: Center(
  415 + child: CupertinoActivityIndicator(),
  416 + ),
  417 + child: EasyRefresh.custom(
  418 + controller: refreshController,
  419 + slivers: [
  420 + SliverList(
  421 + delegate: SliverChildBuilderDelegate(
  422 + (BuildContext context, int position) {
  423 + print("itemBuilder" + list.length.toString());
  424 + PoiModel item = list[position]!;
  425 + return InkWell(
  426 + child: Column(
  427 + children: <Widget>[
  428 + Container(
  429 + margin: EdgeInsets.only(
  430 + top: 8, bottom: 5, left: 10),
  431 + child: Row(
  432 + children: <Widget>[
  433 + Icon(
  434 + Icons.place,
  435 + size: 20.0,
  436 + color: position == 0
  437 + ? Colors.green
  438 + : Colors.grey,
  439 + ),
  440 + Expanded(
  441 + child: Text(item.title,
  442 + style: TextStyle(
  443 + fontSize: 16,
  444 + color: position == 0
  445 + ? Colors.green
  446 + : Color(0xFF787878))))
  447 + ],
  448 + ),
  449 + ),
  450 + Container(
  451 + margin: EdgeInsets.only(
  452 + top: 5, bottom: 5, left: 18),
  453 + alignment: Alignment.centerLeft,
  454 + child: Text(
  455 + item.address!,
  456 + style: TextStyle(
  457 + fontSize: 14,
  458 + color: Color(0xFF646464),
  459 + ),
  460 + ),
  461 + ),
  462 + Divider(
  463 + height: 1,
  464 + )
  465 + ],
  466 + ),
  467 + onTap: () async {
  468 + // await _controller.setCenterCoordinate(
  469 + // LatLng(item.latLng.latitude, item.latLng.longitude),
  470 + // zoomLevel: 16);
  471 + if (Navigator.canPop(context)) {
  472 + Navigator.pop(context, {
  473 + 'address': item.address,
  474 + 'lat': item.latLng!.latitude.toString(),
  475 + 'lng': item.latLng!.longitude.toString()
  476 + });
  477 + }
  478 + },
  479 + );
  480 + },
  481 + childCount: list.length,
  482 + ),
  483 + )
  484 + ],
  485 + onRefresh: () async {
  486 + if (flag) {
  487 + page = 1;
  488 + _loadData(LatLng(latitude, longitude));
  489 + }
  490 + },
  491 + onLoad: () async {
  492 + if (flag) {
  493 + page++;
  494 + _loadData(LatLng(latitude, longitude),
  495 + showloading: false);
  496 + }
  497 + },
  498 + )),
  499 + ),
  500 + ],
  501 + ),
  502 + );
  503 + }
  504 +
  505 + _fetchInputTips(String text) async {
  506 + flag = false;
  507 + page = 1;
  508 + // setState(() {
  509 + // isloading = true;
  510 + // });
  511 +
  512 + /// 逆地理编码(坐标转地址)
  513 + ///
  514 + ///
  515 + await AmapLocation.instance.updatePrivacyShow(true);
  516 + await AmapLocation.instance.updatePrivacyAgree(true);
  517 +
  518 + LatLng latLng = LatLng(latitude, longitude);
  519 + ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(latLng);
  520 +
  521 + // print(await reGeocodeList.toFutureString());
  522 + address = reGeocodeList.formatAddress;
  523 +
  524 + await AmapLocation.instance.updatePrivacyShow(true);
  525 + await AmapLocation.instance.updatePrivacyAgree(true);
  526 + inputTipDatas = await AmapSearch.instance.fetchInputTips(
  527 + text,
  528 + city: "",
  529 + );
  530 + print(inputTipDatas);
  531 +
  532 + poiModel = new PoiModel("当前位置", address, latLng);
  533 + list.clear();
  534 + list.add(poiModel);
  535 + for (var inputTip in inputTipDatas) {
  536 + String? title = await inputTip.name ?? '';
  537 + String? cityStr =
  538 + await (inputTip.district ?? '') + (inputTip.address ?? '');
  539 +
  540 + LatLng? latLng = await inputTip.coordinate;
  541 +
  542 + list.add(new PoiModel(title.toString(), cityStr, latLng));
  543 + }
  544 +
  545 +
  546 + print(list);
  547 +
  548 + setState(() {
  549 + // isloading = false;
  550 + });
  551 + }
  552 +
  553 + void _loadData(LatLng latLng, {showloading = true}) async {
  554 + flag = true;
  555 + setState(() {
  556 + if (showloading) {
  557 + isloading = true;
  558 + }
  559 + });
  560 +
  561 + /// 逆地理编码(坐标转地址)
  562 + ///
  563 + ///
  564 +
  565 + await AmapLocation.instance.updatePrivacyShow(true);
  566 + await AmapLocation.instance.updatePrivacyAgree(true);
  567 + if (page == 1) {
  568 + ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(
  569 + latLng,
  570 + );
  571 + // print(await reGeocodeList.toFutureString());
  572 + address = reGeocodeList.formatAddress;
  573 + poiModel = new PoiModel("当前位置", address, latLng);
  574 + list.clear();
  575 + list.add(poiModel);
  576 + }
  577 + final poiList =
  578 + await AmapSearch.instance.searchAround(latLng, city: "", page: page);
  579 +
  580 + for (var poi in poiList) {
  581 + String? title = await poi.title;
  582 + String? cityName = await poi.cityName;
  583 + String? provinceName = await poi.provinceName;
  584 + String? address = await poi.address;
  585 + LatLng? latLng = await poi.latLng;
  586 + String? bussniss = poi.businessArea;
  587 +
  588 + list.add(new PoiModel(
  589 + title.toString(),
  590 + provinceName.toString() +
  591 + cityName.toString() +
  592 + address.toString() +
  593 + bussniss.toString(),
  594 + latLng));
  595 + }
  596 +
  597 + setState(() {
  598 + if (showloading) {
  599 + isloading = false;
  600 + }
  601 + });
  602 + }
  603 +
  604 + // void searchPoiId(String text) async {
  605 + // await AmapLocation.instance.updatePrivacyShow(true);
  606 + // await AmapLocation.instance.updatePrivacyAgree(true);
  607 + // Poi? poi = await AmapSearch.instance.searchPoiId(
  608 + // text,
  609 + // );
  610 + // print(poi);
  611 + // }
  612 +
  613 + // void searchAroundAddress(String text) async {
  614 + // await AmapLocation.instance.updatePrivacyShow(true);
  615 + // await AmapLocation.instance.updatePrivacyAgree(true);
  616 + // final poiList = await AmapSearch.instance.searchKeyword(
  617 + // text,
  618 + // city: "",
  619 + // );
  620 + // // final poiList = await AmapSearch.instance.searchAround(
  621 + // // LatLng(latitude, longitude),
  622 + // // city: "",
  623 + // // radius: 100000000000000
  624 +
  625 + // // );
  626 +
  627 + // list.clear();
  628 + // list.add(poiModel);
  629 + // for (var poi in poiList) {
  630 + // String? title = await poi.title;
  631 + // LatLng? latLng = await poi.latLng;
  632 + // String? cityName = await poi.cityName;
  633 + // String? provinceName = await poi.provinceName;
  634 + // String? address = await poi.address;
  635 + // list.add(new PoiModel(
  636 + // title.toString(),
  637 + // provinceName.toString() + cityName.toString() + address.toString(),
  638 + // latLng));
  639 + // }
  640 + // setState(() {
  641 + // isloading = false;
  642 + // FocusScope.of(context).requestFocus(FocusNode());
  643 + // });
  644 + // }
  645 +}
  646 +
  647 +class PoiModel {
  648 + LatLng? latLng;
  649 + String title;
  650 + String? address;
  651 +
  652 + PoiModel(this.title, this.address, this.latLng);
  653 +}
1 -import 'dart:async';  
2 -// import 'dart:js_interop'; 1 +// import 'dart:async';
  2 +// // import 'dart:js_interop';
3 3
4 -import 'package:flutter/material.dart'; 4 +// import 'package:flutter/material.dart';
5 5
6 -import 'package:csp_amap_flutter_map/csp_amap_flutter_map.dart';  
7 -import 'package:csp_amap_flutter_location/amap_flutter_location.dart';  
8 -import 'package:csp_amap_flutter_location/amap_location_option.dart';  
9 -import 'package:flutter/cupertino.dart'; 6 +// import 'package:csp_amap_flutter_map/csp_amap_flutter_map.dart';
  7 +// import 'package:csp_amap_flutter_location/amap_flutter_location.dart';
  8 +// import 'package:csp_amap_flutter_location/amap_location_option.dart';
  9 +// import 'package:flutter/cupertino.dart';
10 10
11 -// import 'package:flutter/material.dart'; 11 +// // import 'package:flutter/material.dart';
12 12
13 -import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart'; 13 +// import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart';
14 14
15 -import 'package:flutter_easyrefresh/easy_refresh.dart';  
16 -  
17 -import 'package:one_key/pages/create_store/const_config.dart';  
18 -import 'package:one_key/pages/create_store/map_inputs_model.dart';  
19 -  
20 -import 'package:one_key/res/colors.dart';  
21 -import 'package:one_key/utils/common_utils.dart';  
22 -  
23 -import 'package:one_key/utils/misc.dart';  
24 -  
25 -import 'package:one_key/utils/screen_util.dart';  
26 -import 'package:one_key/utils/utils.dart';  
27 -  
28 -import 'package:one_key/widgets/system_app_bar.dart';  
29 -import 'package:permission_handler/permission_handler.dart';  
30 -  
31 -// import '../../utils/common_utils.dart';  
32 -// import 'package:demo/resources/custom_text_style.dart';  
33 -// import 'package:demo/utils/misc.dart';  
34 -  
35 -// import 'package:demo/widgets/network_state/page_loading.dart';  
36 -  
37 -class MapChoicePointPage extends StatefulWidget {  
38 - final String? long;  
39 - final String? lat;  
40 - MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);  
41 -  
42 - @override  
43 - _MapChoicePointPageState createState() => _MapChoicePointPageState();  
44 -}  
45 -  
46 -class _MapChoicePointPageState extends State<MapChoicePointPage> {  
47 - late AMapController _mapController;  
48 - final double _minZoom = 3;  
49 - final double _maxZoom = 20;  
50 - String? _currentZoom;  
51 - // List<Poi>? poiList;  
52 - static List<PoiModel?> list = [];  
53 - static List<PoiModel> searchlist = [];  
54 - PoiModel? poiModel;  
55 - String keyword = "";  
56 - String? address = "";  
57 - bool isloading = true;  
58 -  
59 - double latitude = 39.684670899;  
60 - double longitude = 118.17630045;  
61 -  
62 - double latitudeLocation = 39.684670899;  
63 - double longitudeLocation = 118.17630045;  
64 -  
65 - List<MapInputsModel> inputTipDatas = [];  
66 - int page = 1;  
67 - EasyRefreshController refreshController = EasyRefreshController();  
68 - bool flag = true;  
69 -  
70 - /// 存储定位结果  
71 - Map<String, Object>? _locationResult;  
72 -  
73 - /// 定位结果监听器  
74 - StreamSubscription<Map<String, Object>>? _locationListener;  
75 -  
76 - /// 地理位置解析结果监听器  
77 - StreamSubscription<Map<String, Object>>? _geocodeSearchListener;  
78 -  
79 - /// 高德定位插件实例  
80 - final AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();  
81 -  
82 - @override  
83 - void initState() {  
84 - super.initState();  
85 -  
86 - if (widget.long != null && widget.long != '' && widget.long != 'null') {  
87 - longitude = double.parse(widget.long!);  
88 - }  
89 - if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {  
90 - latitude = double.parse(widget.lat!);  
91 - }  
92 -  
93 - WidgetsBinding.instance.addPostFrameCallback((_) async {  
94 - AMapInitializer.init(context, apiKey: ConstConfig.amapApiKeys);  
95 - AMapInitializer.updatePrivacyAgree(ConstConfig.amapPrivacyStatement);  
96 -  
97 - AMapFlutterLocation.setApiKey("1dbf56e2e8a4d0e4cdc2df9efd36bc71",  
98 - "dfb64c0463cb53927914364b5c09aba0",  
99 - ohosKey: "7c2081e92ec65bfffa2df0a5464f0c7b");  
100 -  
101 - /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作  
102 - ///  
103 - /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy  
104 - /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>  
105 - ///  
106 - /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy  
107 - ///  
108 - /// [hasContains] 隐私声明中是否包含高德隐私政策说明  
109 - ///  
110 - /// [hasShow] 隐私权政策是否弹窗展示告知用户  
111 - AMapFlutterLocation.updatePrivacyShow(true, true);  
112 -  
113 - /// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作  
114 - ///  
115 - /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy  
116 - ///  
117 - /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>  
118 - ///  
119 - /// [hasAgree] 隐私权政策是否已经取得用户同意  
120 - AMapFlutterLocation.updatePrivacyAgree(true);  
121 - _requestLocationPermission();  
122 -  
123 - // ama  
124 - // let marker = new AMap.Marker({//添加标记点  
125 - // position: this.position,  
126 - // map: map  
127 - });  
128 -  
129 - _geocodeSearchListener = _locationPlugin  
130 - .onGeocodeSearchChange()  
131 - .listen((Map<String, Object> result) {  
132 - // setState(() {  
133 -  
134 - if (result.containsKey('errorCode')) {  
135 - Utils.showToast(result['errorInfo'].toString());  
136 - } else {  
137 - _locationResult = result;  
138 -  
139 - print(_locationResult);  
140 - }  
141 - });  
142 -  
143 - /// 注册定位结果监听  
144 - /// 通过监听器接收定位结果并更新UI  
145 - _locationListener = _locationPlugin  
146 - .onLocationChanged()  
147 - .listen((Map<String, Object> result) {  
148 - // setState(() {  
149 -  
150 - if (result.containsKey('errorCode')) {  
151 - Utils.showToast(result['errorInfo'].toString());  
152 - } else {  
153 - _locationResult = result;  
154 -  
155 - print(_locationResult);  
156 -  
157 - if (result['latitude'] == null || result['latitude'] == '') //网络不好,定位失败  
158 - {  
159 - // App.sp.setString("lat", "39.684670899");  
160 - // App.sp.setString("lng", "118.17630045");  
161 - } else {  
162 - if (widget.long == null ||  
163 - widget.long == '' ||  
164 - widget.long == 'null') {  
165 - latitude = double.parse(result['latitude'].toString());  
166 - longitude = double.parse(result['longitude'].toString());  
167 - // if (_mapController != null) {  
168 - _mapController.moveCamera(  
169 - CameraUpdate.newLatLng(LatLng(latitude, longitude)));  
170 -  
171 - // }  
172 - page = 1;  
173 -  
174 - // _loadData(LatLng(latitude, longitude));  
175 -  
176 - // setState(() {});  
177 - }  
178 - latitudeLocation = latitude;  
179 - longitudeLocation = longitude;  
180 - _mapController.moveCamera(  
181 - CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),  
182 - animated: true,  
183 - );  
184 - _loadData(LatLng(latitude, longitude));  
185 - }  
186 - }  
187 - });  
188 - }  
189 -  
190 - @override  
191 - void dispose() {  
192 - super.dispose();  
193 -  
194 - /// 移除定位监听  
195 - /// 防止内存泄漏  
196 - if (null != _locationListener) {  
197 - _locationListener?.cancel();  
198 - }  
199 -  
200 - if (null != _geocodeSearchListener) {  
201 - _geocodeSearchListener?.cancel();  
202 - }  
203 -  
204 - /// 销毁定位  
205 - /// 释放定位资源  
206 - _locationPlugin.destroy();  
207 - }  
208 -  
209 - // Future<bool> checkLocationPermission() async {  
210 - // PermissionStatus permissionStatus = await Permission.location.status;  
211 - // if (permissionStatus == PermissionStatus.granted) {  
212 - // return true;  
213 - // } else {  
214 - // return false;  
215 - // }  
216 - // }  
217 -  
218 - /// 检查权限并定  
219 - // _getLocationPermission() async {  
220 - // if (!(await checkPermission(Permission.location))) {  
221 - // //没有定位权限  
222 -  
223 - // //申请定位权限  
224 - // _requestLocationPermission();  
225 - // } else {  
226 - // //去定位  
227 - // _requestLocationPermission();  
228 - // }  
229 - // }  
230 -  
231 - /// 设置定位参数  
232 - /// 配置定位选项,如精度、频率等  
233 - void _setLocationOption() {  
234 - AMapLocationOption locationOption = new AMapLocationOption();  
235 -  
236 - /// 是否单次定位  
237 - /// false表示连续定位  
238 - locationOption.onceLocation = true;  
239 -  
240 - /// 是否需要返回逆地理信息  
241 - /// true表示需要返回地址信息  
242 - locationOption.needAddress = true;  
243 -  
244 - /// 是否需要返回逆地理编码信息  
245 - locationOption.locatingWithReGeocode = true;  
246 -  
247 - /// 逆地理信息的语言类型  
248 - /// 默认为自动适配当前系统语言  
249 - locationOption.geoLanguage = GeoLanguage.DEFAULT;  
250 -  
251 - /// iOS 14定位精度权限设置  
252 - /// 设置为模糊定位精度  
253 - locationOption.desiredLocationAccuracyAuthorizationMode =  
254 - AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;  
255 -  
256 - /// iOS 14精确定位目的key  
257 - /// 需要与info.plist中配置一致  
258 - locationOption.fullAccuracyPurposeKey = "AMapLocationScene";  
259 -  
260 - /// 设置Android端连续定位的定位间隔  
261 - /// 单位:毫秒  
262 - locationOption.locationInterval = 2000;  
263 -  
264 - /// 设置Android端的定位模式  
265 - /// 可选值:  
266 - /// [AMapLocationMode.Battery_Saving] 低功耗模式  
267 - /// [AMapLocationMode.Device_Sensors] 仅设备模式  
268 - /// [AMapLocationMode.Hight_Accuracy] 高精度模式  
269 - locationOption.locationMode = AMapLocationMode.Hight_Accuracy;  
270 -  
271 - /// 设置iOS端的定位最小更新距离  
272 - /// -1表示不限制距离  
273 - locationOption.distanceFilter = -1;  
274 -  
275 - /// 设置iOS端期望的定位精度  
276 - /// 可选值:  
277 - /// [DesiredAccuracy.Best] 最高精度  
278 - /// [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度  
279 - /// [DesiredAccuracy.NearestTenMeters] 10米  
280 - /// [DesiredAccuracy.Kilometer] 1000米  
281 - /// [DesiredAccuracy.ThreeKilometers] 3000米  
282 - locationOption.desiredAccuracy = DesiredAccuracy.Best;  
283 -  
284 - /// 设置iOS端是否允许系统暂停定位  
285 - /// false表示不允许系统暂停定位  
286 - locationOption.pausesLocationUpdatesAutomatically = false;  
287 -  
288 - /// 将定位参数设置给定位插件  
289 - _locationPlugin.setLocationOption(locationOption);  
290 - }  
291 -  
292 - /// 获取定位权限  
293 - _requestLocationPermission() async {  
294 - /// [hasShow] 隐私权政策是否弹窗展示告知用户  
295 - AMapFlutterLocation.updatePrivacyShow(true, true);  
296 -  
297 - /// [hasAgree] 隐私权政策是否已经取得用户同意  
298 - AMapFlutterLocation.updatePrivacyAgree(true);  
299 - // await AMapFlutterLocation.instance.updatePrivacyShow(true);  
300 - // await AmapLocation.instance.updatePrivacyAgree(true);  
301 - bool canLocation = false;  
302 -  
303 - if (!(await checkPermission(Permission.location))) {  
304 - //没有定位权限  
305 -  
306 - //申请定位权限  
307 - canLocation = await requestPermission(Permission.location);  
308 - } else {  
309 - canLocation = true;  
310 - }  
311 - // bool canLocation = await requestPermission(Permission.location);  
312 - // 单次定位  
313 - if (canLocation) {  
314 - Future.delayed(Duration(milliseconds: 200), () async {  
315 - /// [hasShow] 隐私权政策是否弹窗展示告知用户  
316 - AMapFlutterLocation.updatePrivacyShow(true, true);  
317 -  
318 - /// [hasAgree] 隐私权政策是否已经取得用户同意  
319 - AMapFlutterLocation.updatePrivacyAgree(true);  
320 - _startLocation();  
321 - // final location = await AmapLocation.instance.fetchLocation(  
322 - // // needAddress: true,  
323 - // // mode: LocationAccuracy.High,  
324 - // // timeout: Duration(seconds: 10)  
325 - // );  
326 -  
327 - // if (location.city == null || location.city == '') //网络不好,定位失败  
328 - // {  
329 - // // App.sp.setString("lat", "39.684670899");  
330 - // // App.sp.setString("lng", "118.17630045");  
331 - // } else {  
332 - // if (widget.long == null ||  
333 - // widget.long == '' ||  
334 - // widget.long == 'null') {  
335 - // latitude = location.latLng!.latitude;  
336 - // longitude = location.latLng!.longitude;  
337 - // if (_controller != null) {  
338 - // _controller!.setCenterCoordinate(LatLng(  
339 - // location.latLng!.latitude, location.latLng!.longitude));  
340 - // }  
341 -  
342 - // page = 1;  
343 -  
344 - // _loadData(  
345 - // LatLng(location.latLng!.latitude, location.latLng!.longitude));  
346 -  
347 - // setState(() {});  
348 - // }  
349 - // latitudeLocation = location.latLng!.latitude;  
350 - // longitudeLocation = location.latLng!.longitude;  
351 - // }  
352 - });  
353 - } else {  
354 - //无权限  
355 - }  
356 - }  
357 -  
358 - // 开始定位  
359 - /// 设置定位参数并启动定位  
360 - void _startLocation() {  
361 - /// 开始定位之前设置定位参数  
362 - _setLocationOption();  
363 - _locationPlugin.startLocation();  
364 - }  
365 -  
366 - /// 停止定位  
367 - /// 停止定位服务  
368 - void _stopLocation() {  
369 - _locationPlugin.stopLocation();  
370 - }  
371 -  
372 - void onMapCreated(AMapController controller) {  
373 - // setState(() {  
374 - _mapController = controller;  
375 - // _mapController.moveCamera(  
376 - // CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),  
377 - // animated: true,  
378 - // );  
379 - // getApprovalNumber();  
380 - // });  
381 - }  
382 -  
383 - /// 获取审图号  
384 - // void getApprovalNumber() async {  
385 - // //普通地图审图号  
386 - // String mapContentApprovalNumber =  
387 - // (await _mapController.getMapContentApprovalNumber());  
388 - // //卫星地图审图号  
389 - // String satelliteImageApprovalNumber =  
390 - // (await _mapController.getSatelliteImageApprovalNumber());  
391 -  
392 - // print('地图审图号(普通地图): $mapContentApprovalNumber');  
393 - // print('地图审图号(卫星地图): $satelliteImageApprovalNumber');  
394 - // }  
395 -  
396 - //移动视野  
397 - // void _onCameraMove(CameraPosition cameraPosition) {  
398 - // latitude = cameraPosition.target.latitude;  
399 - // longitude = cameraPosition.target.longitude;  
400 - // page = 1;  
401 - // _loadData(cameraPosition.target);  
402 - // }  
403 -  
404 - //移动地图结束  
405 - void _onCameraMoveEnd(CameraPosition cameraPosition) {  
406 - setState(() {  
407 - _currentZoom = '当前缩放级别:${cameraPosition.zoom}';  
408 - });  
409 -  
410 - _mapController.moveCamera(  
411 - CameraUpdate.zoomTo(cameraPosition.zoom),  
412 - animated: true,  
413 - );  
414 - latitude = cameraPosition.target.latitude;  
415 - longitude = cameraPosition.target.longitude;  
416 - page = 1;  
417 - _loadData(cameraPosition.target);  
418 - }  
419 -  
420 - @override  
421 - Widget build(BuildContext context) {  
422 - final AMapWidget amap = AMapWidget(  
423 - initialCameraPosition:  
424 - CameraPosition(target: LatLng(latitude, longitude), zoom: 16),  
425 - onMapCreated: onMapCreated,  
426 - // onCameraMove: _onCameraMove,  
427 - onCameraMoveEnd: _onCameraMoveEnd,  
428 - minMaxZoomPreference: MinMaxZoomPreference(_minZoom, _maxZoom),  
429 - scaleEnabled: true,  
430 - );  
431 -  
432 - return Scaffold(  
433 - resizeToAvoidBottomInset: false, //防止底部布局被顶起  
434 - appBar: SystemAppBar(  
435 - '选择位置信息',  
436 - onTap: () {  
437 - if (Navigator.canPop(context)) {  
438 - Navigator.pop(context);  
439 - }  
440 - },  
441 - ),  
442 -  
443 - body: Column(  
444 - children: <Widget>[  
445 - // Theme(  
446 - // data: new  
447 - // ThemeData(  
448 - // // primaryColor: MyColours.color_438E93,  
449 - // // hintColor: MyColours.color_438E93),  
450 - // child:  
451 - // Container(  
452 - // color: MyColours.color_438E93,  
453 - // decoration: BoxDecoration(  
454 - // color: MyColours.color_438E93,  
455 - // boxShadow: [  
456 - // BoxShadow(color: Colors.white, spreadRadius: 1),  
457 - // ],  
458 - // ),  
459 -  
460 - // padding: EdgeInsets.all(5),  
461 - // child:  
462 -  
463 - // ),  
464 - // ),  
465 - // ListView.builder(  
466 - // shrinkWrap: true,  
467 - // itemCount: inputTipDatas.length,  
468 - // itemBuilder: (context, index) {  
469 - // InputTip inputTip = inputTipDatas[index];  
470 - // return InkWell(  
471 - // onTap: () {  
472 - // // searchAroundAddress(inputTip.name ?? '');  
473 - // // searchPoiId(inputTip.poiId ?? '');  
474 - // // _loadData(inputTip.coordinate ??  
475 - // // LatLng(latitude, longitude));  
476 - // },  
477 - // child: Container(  
478 - // child: Row(  
479 - // children: [  
480 - // Text(  
481 - // inputTip.name ?? '',  
482 - // style: TextStyle(  
483 - // fontSize: font(15),  
484 - // color: MyColours.color_515151),  
485 - // ),  
486 - // HEmptyView(10),  
487 - // Expanded(  
488 - // child: Text(  
489 - // (inputTip.district ?? '') +  
490 - // (inputTip.address ?? ''),  
491 - // style: TextStyle(  
492 - // fontSize: font(13),  
493 - // color: MyColours.color_999999),  
494 - // ),  
495 - // ),  
496 - // ],  
497 - // )));  
498 - // })  
499 - // ],  
500 - // ),  
501 -  
502 - Stack(  
503 - children: [  
504 - Container(  
505 - height: w(300),  
506 - child: Stack(  
507 - children: <Widget>[  
508 - amap,  
509 - // AmapView(  
510 - // showZoomControl: false,  
511 -  
512 - // /// 是否显示指南针控件  
513 - // showCompass: true,  
514 -  
515 - // /// 是否显示比例尺控件  
516 - // showScaleControl: true,  
517 -  
518 - // /// 是否使能缩放手势  
519 - // zoomGesturesEnabled: true,  
520 -  
521 - // /// 是否使能滚动手势  
522 - // scrollGesturesEnabled: true,  
523 -  
524 - // /// 是否使能旋转手势  
525 - // rotateGestureEnabled: false,  
526 - // centerCoordinate: LatLng(latitude, longitude),  
527 - // maskDelay: Duration(milliseconds: 500),  
528 - // zoomLevel: 19,  
529 - // onMapCreated: (controller) async {  
530 - // _controller = controller;  
531 - // _controller!  
532 - // .setCenterCoordinate(LatLng(latitude, longitude));  
533 - // // if (await requestPermission(PermissionGroup.location)) {  
534 - // // await controller.showMyLocation(true);  
535 - // // await controller?.showLocateControl(true);  
536 - // // final latLng = await _controller?.getLocation(  
537 - // // delay: Duration(seconds: 2));  
538 - // // await enableFluttifyLog(false); // 关闭log  
539 - // // _loadData(latLng);  
540 - // // } else {  
541 - // // //无权限  
542 - // // _showLocPemWidget();  
543 - // // }  
544 - // },  
545 - // // markers: [],  
546 - // onMapMoveEnd: (MapMove move) async {  
547 - // latitude = move.coordinate!.latitude;  
548 - // longitude = move.coordinate!.longitude;  
549 - // page = 1;  
550 - // _loadData(move.coordinate!);  
551 - // },  
552 - // ),  
553 - Center(  
554 - child: Icon(  
555 - Icons.place,  
556 - size: w(32),  
557 - color: Color(0xFFFF0000),  
558 - ),  
559 - ),  
560 - Positioned(  
561 - right: w(10),  
562 - bottom: w(10),  
563 - child: InkWell(  
564 - onTap: () {  
565 - _mapController.moveCamera(  
566 - CameraUpdate.newLatLng(  
567 - LatLng(latitudeLocation, longitudeLocation)),  
568 - animated: true,  
569 - );  
570 - },  
571 - child: Container(  
572 - decoration: BoxDecoration(  
573 - color: MyColours.color_ffffff,  
574 - borderRadius: BorderRadius.circular(r(5))),  
575 - padding: EdgeInsets.all(w(5)),  
576 - child: Image.asset(  
577 - Utils.getImgPath('location_map'),  
578 - width: w(25),  
579 - ),  
580 - )),  
581 - )  
582 - ],  
583 - ),  
584 - ),  
585 - Positioned(  
586 - top: w(10),  
587 - left: w(20),  
588 - right: w(20),  
589 - child: Container(  
590 - // height: w(45),  
591 - padding: EdgeInsets.symmetric(vertical: w(10)),  
592 - decoration: BoxDecoration(  
593 - color: Colors.white,  
594 - borderRadius: BorderRadius.circular(r(10))),  
595 - child: TextField(  
596 - textAlignVertical: TextAlignVertical.center,  
597 - style: TextStyle(  
598 - color: MyColours.color_515151,  
599 - fontSize: font(15),  
600 - ),  
601 - controller:  
602 - TextEditingController.fromValue(TextEditingValue(  
603 - // 设置内容  
604 - text: keyword,  
605 - selection: TextSelection.fromPosition(TextPosition(  
606 - affinity: TextAffinity.downstream,  
607 - offset: keyword.length)),  
608 - // 保持光标在最后  
609 - )),  
610 - decoration: InputDecoration(  
611 - // border: b,  
612 - // border: OutlineInputBorder(  
613 - // borderRadius: BorderRadius.all(Radius.circular(40)),  
614 - // ),  
615 - border: OutlineInputBorder(borderSide: BorderSide.none),  
616 - hintText: '输入关键字',  
617 - isCollapsed: true,  
618 -  
619 - hintStyle: TextStyle(  
620 - color: MyColours.color_999999, fontSize: font(15)),  
621 - // contentPadding: const EdgeInsets.symmetric(  
622 - // vertical: 8, horizontal: 1),  
623 - prefixIconConstraints: BoxConstraints(maxWidth: w(40)),  
624 - prefixIcon: Padding(  
625 - padding: EdgeInsets.only(left: w(10), right: w(10)),  
626 - child: SizedBox(  
627 - width: w(30),  
628 - child: Image.asset(  
629 - Utils.getImgPath('search_black'),  
630 - ))),  
631 - suffixIconConstraints: BoxConstraints(maxWidth: w(32)),  
632 - suffixIcon: InkWell(  
633 - child: Padding(  
634 - padding: EdgeInsets.only(left: w(10), right: w(10)),  
635 - child: SizedBox(  
636 - width: w(22),  
637 - child: Image.asset(  
638 - Utils.getImgPath('delete_black'),  
639 - ))),  
640 - onTap: () {  
641 - keyword = "";  
642 - setState(() {});  
643 - },  
644 - ),  
645 - fillColor: Colors.white,  
646 - filled: true,  
647 - ),  
648 -  
649 - inputFormatters: [],  
650 - //内容改变的回调  
651 - onChanged: (text) {  
652 - print('change $text');  
653 - keyword = text;  
654 -  
655 - //搜索  
656 -  
657 - if (text != null && text.trim().length > 0) {  
658 - JhCommonUtils.debounce(  
659 - () => _fetchInputTips(text.toString()));  
660 - }  
661 - },  
662 - //内容提交(按回车)的回调  
663 - onSubmitted: (text) {  
664 - print('submit $text');  
665 - // 触发关闭弹出来的键盘。  
666 - keyword = text;  
667 - FocusScope.of(context).requestFocus(FocusNode());  
668 - setState(() {  
669 - // isloading = true;  
670 - });  
671 -  
672 - // _fetchInputTips(text.toString());  
673 -  
674 - // searchAroundAddress(text.toString());  
675 - },  
676 - //按回车时调用  
677 - onEditingComplete: () {  
678 - print('onEditingComplete');  
679 - },  
680 - ),  
681 - ),  
682 - )  
683 - ],  
684 - ),  
685 -  
686 - Expanded(  
687 - flex: 1,  
688 - child: Visibility(  
689 - visible: !isloading,  
690 - maintainSize: false,  
691 - maintainSemantics: false,  
692 - maintainInteractivity: false,  
693 - replacement: Center(  
694 - child: CupertinoActivityIndicator(),  
695 - ),  
696 - child: EasyRefresh.custom(  
697 - controller: refreshController,  
698 - slivers: [  
699 - SliverList(  
700 - delegate: SliverChildBuilderDelegate(  
701 - (BuildContext context, int position) {  
702 - print("itemBuilder" + list.length.toString());  
703 - PoiModel item = list[position]!;  
704 - return InkWell(  
705 - child: Column(  
706 - children: <Widget>[  
707 - Container(  
708 - margin: EdgeInsets.only(  
709 - top: 8, bottom: 5, left: 10),  
710 - child: Row(  
711 - children: <Widget>[  
712 - Icon(  
713 - Icons.place,  
714 - size: 20.0,  
715 - color: position == 0  
716 - ? Colors.green  
717 - : Colors.grey,  
718 - ),  
719 - Expanded(  
720 - child: Text(item.title,  
721 - style: TextStyle(  
722 - fontSize: 16,  
723 - color: position == 0  
724 - ? Colors.green  
725 - : Color(0xFF787878))))  
726 - ],  
727 - ),  
728 - ),  
729 - Container(  
730 - margin: EdgeInsets.only(  
731 - top: 5, bottom: 5, left: 18),  
732 - alignment: Alignment.centerLeft,  
733 - child: Text(  
734 - item.address!,  
735 - style: TextStyle(  
736 - fontSize: 14,  
737 - color: Color(0xFF646464),  
738 - ),  
739 - ),  
740 - ),  
741 - Divider(  
742 - height: 1,  
743 - )  
744 - ],  
745 - ),  
746 - onTap: () async {  
747 - // await _controller.setCenterCoordinate(  
748 - // LatLng(item.latLng.latitude, item.latLng.longitude),  
749 - // zoomLevel: 16);  
750 - if (Navigator.canPop(context)) {  
751 - Navigator.pop(context, {  
752 - 'address': item.address,  
753 - 'lat': item.latLng!.latitude.toString(),  
754 - 'lng': item.latLng!.longitude.toString()  
755 - });  
756 - }  
757 - },  
758 - );  
759 - },  
760 - childCount: list.length,  
761 - ),  
762 - )  
763 - ],  
764 - onRefresh: () async {  
765 - if (flag) {  
766 - page = 1;  
767 - _loadData(LatLng(latitude, longitude));  
768 - }  
769 - },  
770 - onLoad: () async {  
771 - if (flag) {  
772 - page++;  
773 - _loadData(LatLng(latitude, longitude),  
774 - showloading: false);  
775 - }  
776 - },  
777 - )),  
778 - ),  
779 - ],  
780 - ),  
781 - );  
782 - }  
783 -  
784 - _fetchInputTips(String text) async {  
785 - flag = false;  
786 - page = 1;  
787 - // setState(() {  
788 - // isloading = true;  
789 - // });  
790 -  
791 - /// 逆地理编码(坐标转地址)  
792 - ///  
793 - ///  
794 - // await AmapLocation.instance.updatePrivacyShow(true);  
795 - // await AmapLocation.instance.updatePrivacyAgree(true);  
796 -  
797 - LatLng latLng = LatLng(latitude, longitude);  
798 -  
799 - address = await _locationPlugin  
800 - .onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);  
801 -  
802 - // await AmapLocation.instance.updatePrivacyShow(true);  
803 - // await AmapLocation.instance.updatePrivacyAgree(true);  
804 -  
805 - List<dynamic> temp = await _locationPlugin.doInputtipsRequest(  
806 - text,  
807 - city: "",  
808 - );  
809 -  
810 - inputTipDatas = [];  
811 -  
812 - temp.forEach((element) {  
813 - inputTipDatas.add(MapInputsModel.fromJson(element));  
814 - });  
815 -  
816 - print(inputTipDatas);  
817 - poiModel = new PoiModel("当前位置", address, latLng);  
818 - list.clear();  
819 - list.add(poiModel);  
820 - for (var inputTip in inputTipDatas) {  
821 - String? title = await inputTip.name ?? '';  
822 - String? cityStr = (inputTip.district ?? '') + (inputTip.city ?? '');  
823 -  
824 - // LatLng? latLng = await inputTip.point;  
825 -  
826 - list.add(new PoiModel(title.toString(), cityStr, latLng));  
827 - }  
828 -  
829 - print(list);  
830 -  
831 - setState(() {  
832 - // isloading = false;  
833 - });  
834 - }  
835 -  
836 - void _loadData(LatLng latLng, {showloading = true}) async {  
837 - flag = true;  
838 - setState(() {  
839 - if (showloading) {  
840 - isloading = true;  
841 - }  
842 - });  
843 -  
844 - /// 逆地理编码(坐标转地址)  
845 - ///  
846 - ///  
847 - ///  
848 -  
849 - // await AmapLocation.instance.updatePrivacyShow(true);  
850 - // await AmapLocation.instance.updatePrivacyAgree(true);  
851 - if (page == 1) {  
852 - address = await _locationPlugin  
853 - .onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);  
854 - poiModel = new PoiModel("当前位置", address, latLng);  
855 - list.clear();  
856 - list.add(poiModel);  
857 - }  
858 - // final poiList  
859 - List<dynamic> temp = await _locationPlugin.poiSearchAround(  
860 - keyword, latLng.longitude, latLng.latitude);  
861 -  
862 - List<MapRoundSearchModel> searchData = [];  
863 -  
864 - temp.forEach((element) {  
865 - searchData.add(MapRoundSearchModel.fromJson(element));  
866 - });  
867 -  
868 - print(searchData);  
869 -  
870 - for (var poi in searchData) {  
871 - String? title = await poi.title;  
872 - String? cityName = await poi.cityName;  
873 - String? provinceName = await poi.provinceName;  
874 - String? snippet = await poi.snippet;  
875 - String? adName = await poi.adName;  
876 - LatLng? latLng = LatLng(poi.latitude ?? 0, poi.longitude ?? 0);  
877 - String? bussniss = poi.businessArea;  
878 -  
879 - list.add(new PoiModel(  
880 - title.toString(),  
881 - provinceName.toString() +  
882 - cityName.toString() +  
883 - adName.toString() +  
884 - // address.toString() +  
885 - bussniss.toString() +  
886 - snippet.toString(),  
887 - latLng));  
888 - }  
889 -  
890 - setState(() {  
891 - if (showloading) {  
892 - isloading = false;  
893 - }  
894 - });  
895 - }  
896 -  
897 - // void searchPoiId(String text) async {  
898 - // await AmapLocation.instance.updatePrivacyShow(true);  
899 - // await AmapLocation.instance.updatePrivacyAgree(true);  
900 - // Poi? poi = await AmapSearch.instance.searchPoiId(  
901 - // text,  
902 - // );  
903 - // print(poi);  
904 - // }  
905 -  
906 - // void searchAroundAddress(String text) async {  
907 - // await AmapLocation.instance.updatePrivacyShow(true);  
908 - // await AmapLocation.instance.updatePrivacyAgree(true);  
909 - // final poiList = await AmapSearch.instance.searchKeyword(  
910 - // text,  
911 - // city: "",  
912 - // );  
913 - // // final poiList = await AmapSearch.instance.searchAround(  
914 - // // LatLng(latitude, longitude),  
915 - // // city: "",  
916 - // // radius: 100000000000000  
917 -  
918 - // // );  
919 -  
920 - // list.clear();  
921 - // list.add(poiModel);  
922 - // for (var poi in poiList) {  
923 - // String? title = await poi.title;  
924 - // LatLng? latLng = await poi.latLng;  
925 - // String? cityName = await poi.cityName;  
926 - // String? provinceName = await poi.provinceName;  
927 - // String? address = await poi.address;  
928 - // list.add(new PoiModel(  
929 - // title.toString(),  
930 - // provinceName.toString() + cityName.toString() + address.toString(),  
931 - // latLng));  
932 - // }  
933 - // setState(() {  
934 - // isloading = false;  
935 - // FocusScope.of(context).requestFocus(FocusNode());  
936 - // });  
937 - // }  
938 -}  
939 -  
940 -class PoiModel {  
941 - LatLng? latLng;  
942 - String title;  
943 - String? address;  
944 -  
945 - PoiModel(this.title, this.address, this.latLng);  
946 -} 15 +// import 'package:flutter_easyrefresh/easy_refresh.dart';
  16 +
  17 +// import 'package:one_key/pages/create_store/const_config.dart';
  18 +// import 'package:one_key/pages/create_store/map_inputs_model.dart';
  19 +
  20 +// import 'package:one_key/res/colors.dart';
  21 +// import 'package:one_key/utils/common_utils.dart';
  22 +
  23 +// import 'package:one_key/utils/misc.dart';
  24 +
  25 +// import 'package:one_key/utils/screen_util.dart';
  26 +// import 'package:one_key/utils/utils.dart';
  27 +
  28 +// import 'package:one_key/widgets/system_app_bar.dart';
  29 +// import 'package:permission_handler/permission_handler.dart';
  30 +
  31 +// // import '../../utils/common_utils.dart';
  32 +// // import 'package:demo/resources/custom_text_style.dart';
  33 +// // import 'package:demo/utils/misc.dart';
  34 +
  35 +// // import 'package:demo/widgets/network_state/page_loading.dart';
  36 +
  37 +// class MapChoicePointPage extends StatefulWidget {
  38 +// final String? long;
  39 +// final String? lat;
  40 +// MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);
  41 +
  42 +// @override
  43 +// _MapChoicePointPageState createState() => _MapChoicePointPageState();
  44 +// }
  45 +
  46 +// class _MapChoicePointPageState extends State<MapChoicePointPage> {
  47 +// late AMapController _mapController;
  48 +// final double _minZoom = 3;
  49 +// final double _maxZoom = 20;
  50 +// String? _currentZoom;
  51 +// // List<Poi>? poiList;
  52 +// static List<PoiModel?> list = [];
  53 +// static List<PoiModel> searchlist = [];
  54 +// PoiModel? poiModel;
  55 +// String keyword = "";
  56 +// String? address = "";
  57 +// bool isloading = true;
  58 +
  59 +// double latitude = 39.684670899;
  60 +// double longitude = 118.17630045;
  61 +
  62 +// double latitudeLocation = 39.684670899;
  63 +// double longitudeLocation = 118.17630045;
  64 +
  65 +// List<MapInputsModel> inputTipDatas = [];
  66 +// int page = 1;
  67 +// EasyRefreshController refreshController = EasyRefreshController();
  68 +// bool flag = true;
  69 +
  70 +// /// 存储定位结果
  71 +// Map<String, Object>? _locationResult;
  72 +
  73 +// /// 定位结果监听器
  74 +// StreamSubscription<Map<String, Object>>? _locationListener;
  75 +
  76 +// /// 地理位置解析结果监听器
  77 +// StreamSubscription<Map<String, Object>>? _geocodeSearchListener;
  78 +
  79 +// /// 高德定位插件实例
  80 +// final AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();
  81 +
  82 +// @override
  83 +// void initState() {
  84 +// super.initState();
  85 +
  86 +// if (widget.long != null && widget.long != '' && widget.long != 'null') {
  87 +// longitude = double.parse(widget.long!);
  88 +// }
  89 +// if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {
  90 +// latitude = double.parse(widget.lat!);
  91 +// }
  92 +
  93 +// WidgetsBinding.instance.addPostFrameCallback((_) async {
  94 +// AMapInitializer.init(context, apiKey: ConstConfig.amapApiKeys);
  95 +// AMapInitializer.updatePrivacyAgree(ConstConfig.amapPrivacyStatement);
  96 +
  97 +// AMapFlutterLocation.setApiKey("1dbf56e2e8a4d0e4cdc2df9efd36bc71",
  98 +// "dfb64c0463cb53927914364b5c09aba0",
  99 +// ohosKey: "7c2081e92ec65bfffa2df0a5464f0c7b");
  100 +
  101 +// /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作
  102 +// ///
  103 +// /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
  104 +// /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
  105 +// ///
  106 +// /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
  107 +// ///
  108 +// /// [hasContains] 隐私声明中是否包含高德隐私政策说明
  109 +// ///
  110 +// /// [hasShow] 隐私权政策是否弹窗展示告知用户
  111 +// AMapFlutterLocation.updatePrivacyShow(true, true);
  112 +
  113 +// /// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作
  114 +// ///
  115 +// /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
  116 +// ///
  117 +// /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
  118 +// ///
  119 +// /// [hasAgree] 隐私权政策是否已经取得用户同意
  120 +// AMapFlutterLocation.updatePrivacyAgree(true);
  121 +// _requestLocationPermission();
  122 +
  123 +// // ama
  124 +// // let marker = new AMap.Marker({//添加标记点
  125 +// // position: this.position,
  126 +// // map: map
  127 +// });
  128 +
  129 +// _geocodeSearchListener = _locationPlugin
  130 +// .onGeocodeSearchChange()
  131 +// .listen((Map<String, Object> result) {
  132 +// // setState(() {
  133 +
  134 +// if (result.containsKey('errorCode')) {
  135 +// Utils.showToast(result['errorInfo'].toString());
  136 +// } else {
  137 +// _locationResult = result;
  138 +
  139 +// print(_locationResult);
  140 +// }
  141 +// });
  142 +
  143 +// /// 注册定位结果监听
  144 +// /// 通过监听器接收定位结果并更新UI
  145 +// _locationListener = _locationPlugin
  146 +// .onLocationChanged()
  147 +// .listen((Map<String, Object> result) {
  148 +// // setState(() {
  149 +
  150 +// if (result.containsKey('errorCode')) {
  151 +// Utils.showToast(result['errorInfo'].toString());
  152 +// } else {
  153 +// _locationResult = result;
  154 +
  155 +// print(_locationResult);
  156 +
  157 +// if (result['latitude'] == null || result['latitude'] == '') //网络不好,定位失败
  158 +// {
  159 +// // App.sp.setString("lat", "39.684670899");
  160 +// // App.sp.setString("lng", "118.17630045");
  161 +// } else {
  162 +// if (widget.long == null ||
  163 +// widget.long == '' ||
  164 +// widget.long == 'null') {
  165 +// latitude = double.parse(result['latitude'].toString());
  166 +// longitude = double.parse(result['longitude'].toString());
  167 +// // if (_mapController != null) {
  168 +// _mapController.moveCamera(
  169 +// CameraUpdate.newLatLng(LatLng(latitude, longitude)));
  170 +
  171 +// // }
  172 +// page = 1;
  173 +
  174 +// // _loadData(LatLng(latitude, longitude));
  175 +
  176 +// // setState(() {});
  177 +// }
  178 +// latitudeLocation = latitude;
  179 +// longitudeLocation = longitude;
  180 +// _mapController.moveCamera(
  181 +// CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),
  182 +// animated: true,
  183 +// );
  184 +// _loadData(LatLng(latitude, longitude));
  185 +// }
  186 +// }
  187 +// });
  188 +// }
  189 +
  190 +// @override
  191 +// void dispose() {
  192 +// super.dispose();
  193 +
  194 +// /// 移除定位监听
  195 +// /// 防止内存泄漏
  196 +// if (null != _locationListener) {
  197 +// _locationListener?.cancel();
  198 +// }
  199 +
  200 +// if (null != _geocodeSearchListener) {
  201 +// _geocodeSearchListener?.cancel();
  202 +// }
  203 +
  204 +// /// 销毁定位
  205 +// /// 释放定位资源
  206 +// _locationPlugin.destroy();
  207 +// }
  208 +
  209 +// // Future<bool> checkLocationPermission() async {
  210 +// // PermissionStatus permissionStatus = await Permission.location.status;
  211 +// // if (permissionStatus == PermissionStatus.granted) {
  212 +// // return true;
  213 +// // } else {
  214 +// // return false;
  215 +// // }
  216 +// // }
  217 +
  218 +// /// 检查权限并定
  219 +// // _getLocationPermission() async {
  220 +// // if (!(await checkPermission(Permission.location))) {
  221 +// // //没有定位权限
  222 +
  223 +// // //申请定位权限
  224 +// // _requestLocationPermission();
  225 +// // } else {
  226 +// // //去定位
  227 +// // _requestLocationPermission();
  228 +// // }
  229 +// // }
  230 +
  231 +// /// 设置定位参数
  232 +// /// 配置定位选项,如精度、频率等
  233 +// void _setLocationOption() {
  234 +// AMapLocationOption locationOption = new AMapLocationOption();
  235 +
  236 +// /// 是否单次定位
  237 +// /// false表示连续定位
  238 +// locationOption.onceLocation = true;
  239 +
  240 +// /// 是否需要返回逆地理信息
  241 +// /// true表示需要返回地址信息
  242 +// locationOption.needAddress = true;
  243 +
  244 +// /// 是否需要返回逆地理编码信息
  245 +// locationOption.locatingWithReGeocode = true;
  246 +
  247 +// /// 逆地理信息的语言类型
  248 +// /// 默认为自动适配当前系统语言
  249 +// locationOption.geoLanguage = GeoLanguage.DEFAULT;
  250 +
  251 +// /// iOS 14定位精度权限设置
  252 +// /// 设置为模糊定位精度
  253 +// locationOption.desiredLocationAccuracyAuthorizationMode =
  254 +// AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;
  255 +
  256 +// /// iOS 14精确定位目的key
  257 +// /// 需要与info.plist中配置一致
  258 +// locationOption.fullAccuracyPurposeKey = "AMapLocationScene";
  259 +
  260 +// /// 设置Android端连续定位的定位间隔
  261 +// /// 单位:毫秒
  262 +// locationOption.locationInterval = 2000;
  263 +
  264 +// /// 设置Android端的定位模式
  265 +// /// 可选值:
  266 +// /// [AMapLocationMode.Battery_Saving] 低功耗模式
  267 +// /// [AMapLocationMode.Device_Sensors] 仅设备模式
  268 +// /// [AMapLocationMode.Hight_Accuracy] 高精度模式
  269 +// locationOption.locationMode = AMapLocationMode.Hight_Accuracy;
  270 +
  271 +// /// 设置iOS端的定位最小更新距离
  272 +// /// -1表示不限制距离
  273 +// locationOption.distanceFilter = -1;
  274 +
  275 +// /// 设置iOS端期望的定位精度
  276 +// /// 可选值:
  277 +// /// [DesiredAccuracy.Best] 最高精度
  278 +// /// [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度
  279 +// /// [DesiredAccuracy.NearestTenMeters] 10米
  280 +// /// [DesiredAccuracy.Kilometer] 1000米
  281 +// /// [DesiredAccuracy.ThreeKilometers] 3000米
  282 +// locationOption.desiredAccuracy = DesiredAccuracy.Best;
  283 +
  284 +// /// 设置iOS端是否允许系统暂停定位
  285 +// /// false表示不允许系统暂停定位
  286 +// locationOption.pausesLocationUpdatesAutomatically = false;
  287 +
  288 +// /// 将定位参数设置给定位插件
  289 +// _locationPlugin.setLocationOption(locationOption);
  290 +// }
  291 +
  292 +// /// 获取定位权限
  293 +// _requestLocationPermission() async {
  294 +// /// [hasShow] 隐私权政策是否弹窗展示告知用户
  295 +// AMapFlutterLocation.updatePrivacyShow(true, true);
  296 +
  297 +// /// [hasAgree] 隐私权政策是否已经取得用户同意
  298 +// AMapFlutterLocation.updatePrivacyAgree(true);
  299 +// // await AMapFlutterLocation.instance.updatePrivacyShow(true);
  300 +// // await AmapLocation.instance.updatePrivacyAgree(true);
  301 +// bool canLocation = false;
  302 +
  303 +// if (!(await checkPermission(Permission.location))) {
  304 +// //没有定位权限
  305 +
  306 +// //申请定位权限
  307 +// canLocation = await requestPermission(Permission.location);
  308 +// } else {
  309 +// canLocation = true;
  310 +// }
  311 +// // bool canLocation = await requestPermission(Permission.location);
  312 +// // 单次定位
  313 +// if (canLocation) {
  314 +// Future.delayed(Duration(milliseconds: 200), () async {
  315 +// /// [hasShow] 隐私权政策是否弹窗展示告知用户
  316 +// AMapFlutterLocation.updatePrivacyShow(true, true);
  317 +
  318 +// /// [hasAgree] 隐私权政策是否已经取得用户同意
  319 +// AMapFlutterLocation.updatePrivacyAgree(true);
  320 +// _startLocation();
  321 +// // final location = await AmapLocation.instance.fetchLocation(
  322 +// // // needAddress: true,
  323 +// // // mode: LocationAccuracy.High,
  324 +// // // timeout: Duration(seconds: 10)
  325 +// // );
  326 +
  327 +// // if (location.city == null || location.city == '') //网络不好,定位失败
  328 +// // {
  329 +// // // App.sp.setString("lat", "39.684670899");
  330 +// // // App.sp.setString("lng", "118.17630045");
  331 +// // } else {
  332 +// // if (widget.long == null ||
  333 +// // widget.long == '' ||
  334 +// // widget.long == 'null') {
  335 +// // latitude = location.latLng!.latitude;
  336 +// // longitude = location.latLng!.longitude;
  337 +// // if (_controller != null) {
  338 +// // _controller!.setCenterCoordinate(LatLng(
  339 +// // location.latLng!.latitude, location.latLng!.longitude));
  340 +// // }
  341 +
  342 +// // page = 1;
  343 +
  344 +// // _loadData(
  345 +// // LatLng(location.latLng!.latitude, location.latLng!.longitude));
  346 +
  347 +// // setState(() {});
  348 +// // }
  349 +// // latitudeLocation = location.latLng!.latitude;
  350 +// // longitudeLocation = location.latLng!.longitude;
  351 +// // }
  352 +// });
  353 +// } else {
  354 +// //无权限
  355 +// }
  356 +// }
  357 +
  358 +// // 开始定位
  359 +// /// 设置定位参数并启动定位
  360 +// void _startLocation() {
  361 +// /// 开始定位之前设置定位参数
  362 +// _setLocationOption();
  363 +// _locationPlugin.startLocation();
  364 +// }
  365 +
  366 +// /// 停止定位
  367 +// /// 停止定位服务
  368 +// void _stopLocation() {
  369 +// _locationPlugin.stopLocation();
  370 +// }
  371 +
  372 +// void onMapCreated(AMapController controller) {
  373 +// // setState(() {
  374 +// _mapController = controller;
  375 +// // _mapController.moveCamera(
  376 +// // CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),
  377 +// // animated: true,
  378 +// // );
  379 +// // getApprovalNumber();
  380 +// // });
  381 +// }
  382 +
  383 +// /// 获取审图号
  384 +// // void getApprovalNumber() async {
  385 +// // //普通地图审图号
  386 +// // String mapContentApprovalNumber =
  387 +// // (await _mapController.getMapContentApprovalNumber());
  388 +// // //卫星地图审图号
  389 +// // String satelliteImageApprovalNumber =
  390 +// // (await _mapController.getSatelliteImageApprovalNumber());
  391 +
  392 +// // print('地图审图号(普通地图): $mapContentApprovalNumber');
  393 +// // print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
  394 +// // }
  395 +
  396 +// //移动视野
  397 +// // void _onCameraMove(CameraPosition cameraPosition) {
  398 +// // latitude = cameraPosition.target.latitude;
  399 +// // longitude = cameraPosition.target.longitude;
  400 +// // page = 1;
  401 +// // _loadData(cameraPosition.target);
  402 +// // }
  403 +
  404 +// //移动地图结束
  405 +// void _onCameraMoveEnd(CameraPosition cameraPosition) {
  406 +// setState(() {
  407 +// _currentZoom = '当前缩放级别:${cameraPosition.zoom}';
  408 +// });
  409 +
  410 +// _mapController.moveCamera(
  411 +// CameraUpdate.zoomTo(cameraPosition.zoom),
  412 +// animated: true,
  413 +// );
  414 +// latitude = cameraPosition.target.latitude;
  415 +// longitude = cameraPosition.target.longitude;
  416 +// page = 1;
  417 +// _loadData(cameraPosition.target);
  418 +// }
  419 +
  420 +// @override
  421 +// Widget build(BuildContext context) {
  422 +// final AMapWidget amap = AMapWidget(
  423 +// initialCameraPosition:
  424 +// CameraPosition(target: LatLng(latitude, longitude), zoom: 16),
  425 +// onMapCreated: onMapCreated,
  426 +// // onCameraMove: _onCameraMove,
  427 +// onCameraMoveEnd: _onCameraMoveEnd,
  428 +// minMaxZoomPreference: MinMaxZoomPreference(_minZoom, _maxZoom),
  429 +// scaleEnabled: true,
  430 +// );
  431 +
  432 +// return Scaffold(
  433 +// resizeToAvoidBottomInset: false, //防止底部布局被顶起
  434 +// appBar: SystemAppBar(
  435 +// '选择位置信息',
  436 +// onTap: () {
  437 +// if (Navigator.canPop(context)) {
  438 +// Navigator.pop(context);
  439 +// }
  440 +// },
  441 +// ),
  442 +
  443 +// body: Column(
  444 +// children: <Widget>[
  445 +// // Theme(
  446 +// // data: new
  447 +// // ThemeData(
  448 +// // // primaryColor: MyColours.color_438E93,
  449 +// // // hintColor: MyColours.color_438E93),
  450 +// // child:
  451 +// // Container(
  452 +// // color: MyColours.color_438E93,
  453 +// // decoration: BoxDecoration(
  454 +// // color: MyColours.color_438E93,
  455 +// // boxShadow: [
  456 +// // BoxShadow(color: Colors.white, spreadRadius: 1),
  457 +// // ],
  458 +// // ),
  459 +
  460 +// // padding: EdgeInsets.all(5),
  461 +// // child:
  462 +
  463 +// // ),
  464 +// // ),
  465 +// // ListView.builder(
  466 +// // shrinkWrap: true,
  467 +// // itemCount: inputTipDatas.length,
  468 +// // itemBuilder: (context, index) {
  469 +// // InputTip inputTip = inputTipDatas[index];
  470 +// // return InkWell(
  471 +// // onTap: () {
  472 +// // // searchAroundAddress(inputTip.name ?? '');
  473 +// // // searchPoiId(inputTip.poiId ?? '');
  474 +// // // _loadData(inputTip.coordinate ??
  475 +// // // LatLng(latitude, longitude));
  476 +// // },
  477 +// // child: Container(
  478 +// // child: Row(
  479 +// // children: [
  480 +// // Text(
  481 +// // inputTip.name ?? '',
  482 +// // style: TextStyle(
  483 +// // fontSize: font(15),
  484 +// // color: MyColours.color_515151),
  485 +// // ),
  486 +// // HEmptyView(10),
  487 +// // Expanded(
  488 +// // child: Text(
  489 +// // (inputTip.district ?? '') +
  490 +// // (inputTip.address ?? ''),
  491 +// // style: TextStyle(
  492 +// // fontSize: font(13),
  493 +// // color: MyColours.color_999999),
  494 +// // ),
  495 +// // ),
  496 +// // ],
  497 +// // )));
  498 +// // })
  499 +// // ],
  500 +// // ),
  501 +
  502 +// Stack(
  503 +// children: [
  504 +// Container(
  505 +// height: w(300),
  506 +// child: Stack(
  507 +// children: <Widget>[
  508 +// amap,
  509 +// // AmapView(
  510 +// // showZoomControl: false,
  511 +
  512 +// // /// 是否显示指南针控件
  513 +// // showCompass: true,
  514 +
  515 +// // /// 是否显示比例尺控件
  516 +// // showScaleControl: true,
  517 +
  518 +// // /// 是否使能缩放手势
  519 +// // zoomGesturesEnabled: true,
  520 +
  521 +// // /// 是否使能滚动手势
  522 +// // scrollGesturesEnabled: true,
  523 +
  524 +// // /// 是否使能旋转手势
  525 +// // rotateGestureEnabled: false,
  526 +// // centerCoordinate: LatLng(latitude, longitude),
  527 +// // maskDelay: Duration(milliseconds: 500),
  528 +// // zoomLevel: 19,
  529 +// // onMapCreated: (controller) async {
  530 +// // _controller = controller;
  531 +// // _controller!
  532 +// // .setCenterCoordinate(LatLng(latitude, longitude));
  533 +// // // if (await requestPermission(PermissionGroup.location)) {
  534 +// // // await controller.showMyLocation(true);
  535 +// // // await controller?.showLocateControl(true);
  536 +// // // final latLng = await _controller?.getLocation(
  537 +// // // delay: Duration(seconds: 2));
  538 +// // // await enableFluttifyLog(false); // 关闭log
  539 +// // // _loadData(latLng);
  540 +// // // } else {
  541 +// // // //无权限
  542 +// // // _showLocPemWidget();
  543 +// // // }
  544 +// // },
  545 +// // // markers: [],
  546 +// // onMapMoveEnd: (MapMove move) async {
  547 +// // latitude = move.coordinate!.latitude;
  548 +// // longitude = move.coordinate!.longitude;
  549 +// // page = 1;
  550 +// // _loadData(move.coordinate!);
  551 +// // },
  552 +// // ),
  553 +// Center(
  554 +// child: Icon(
  555 +// Icons.place,
  556 +// size: w(32),
  557 +// color: Color(0xFFFF0000),
  558 +// ),
  559 +// ),
  560 +// Positioned(
  561 +// right: w(10),
  562 +// bottom: w(10),
  563 +// child: InkWell(
  564 +// onTap: () {
  565 +// _mapController.moveCamera(
  566 +// CameraUpdate.newLatLng(
  567 +// LatLng(latitudeLocation, longitudeLocation)),
  568 +// animated: true,
  569 +// );
  570 +// },
  571 +// child: Container(
  572 +// decoration: BoxDecoration(
  573 +// color: MyColours.color_ffffff,
  574 +// borderRadius: BorderRadius.circular(r(5))),
  575 +// padding: EdgeInsets.all(w(5)),
  576 +// child: Image.asset(
  577 +// Utils.getImgPath('location_map'),
  578 +// width: w(25),
  579 +// ),
  580 +// )),
  581 +// )
  582 +// ],
  583 +// ),
  584 +// ),
  585 +// Positioned(
  586 +// top: w(10),
  587 +// left: w(20),
  588 +// right: w(20),
  589 +// child: Container(
  590 +// // height: w(45),
  591 +// padding: EdgeInsets.symmetric(vertical: w(10)),
  592 +// decoration: BoxDecoration(
  593 +// color: Colors.white,
  594 +// borderRadius: BorderRadius.circular(r(10))),
  595 +// child: TextField(
  596 +// textAlignVertical: TextAlignVertical.center,
  597 +// style: TextStyle(
  598 +// color: MyColours.color_515151,
  599 +// fontSize: font(15),
  600 +// ),
  601 +// controller:
  602 +// TextEditingController.fromValue(TextEditingValue(
  603 +// // 设置内容
  604 +// text: keyword,
  605 +// selection: TextSelection.fromPosition(TextPosition(
  606 +// affinity: TextAffinity.downstream,
  607 +// offset: keyword.length)),
  608 +// // 保持光标在最后
  609 +// )),
  610 +// decoration: InputDecoration(
  611 +// // border: b,
  612 +// // border: OutlineInputBorder(
  613 +// // borderRadius: BorderRadius.all(Radius.circular(40)),
  614 +// // ),
  615 +// border: OutlineInputBorder(borderSide: BorderSide.none),
  616 +// hintText: '输入关键字',
  617 +// isCollapsed: true,
  618 +
  619 +// hintStyle: TextStyle(
  620 +// color: MyColours.color_999999, fontSize: font(15)),
  621 +// // contentPadding: const EdgeInsets.symmetric(
  622 +// // vertical: 8, horizontal: 1),
  623 +// prefixIconConstraints: BoxConstraints(maxWidth: w(40)),
  624 +// prefixIcon: Padding(
  625 +// padding: EdgeInsets.only(left: w(10), right: w(10)),
  626 +// child: SizedBox(
  627 +// width: w(30),
  628 +// child: Image.asset(
  629 +// Utils.getImgPath('search_black'),
  630 +// ))),
  631 +// suffixIconConstraints: BoxConstraints(maxWidth: w(32)),
  632 +// suffixIcon: InkWell(
  633 +// child: Padding(
  634 +// padding: EdgeInsets.only(left: w(10), right: w(10)),
  635 +// child: SizedBox(
  636 +// width: w(22),
  637 +// child: Image.asset(
  638 +// Utils.getImgPath('delete_black'),
  639 +// ))),
  640 +// onTap: () {
  641 +// keyword = "";
  642 +// setState(() {});
  643 +// },
  644 +// ),
  645 +// fillColor: Colors.white,
  646 +// filled: true,
  647 +// ),
  648 +
  649 +// inputFormatters: [],
  650 +// //内容改变的回调
  651 +// onChanged: (text) {
  652 +// print('change $text');
  653 +// keyword = text;
  654 +
  655 +// //搜索
  656 +
  657 +// if (text != null && text.trim().length > 0) {
  658 +// JhCommonUtils.debounce(
  659 +// () => _fetchInputTips(text.toString()));
  660 +// }
  661 +// },
  662 +// //内容提交(按回车)的回调
  663 +// onSubmitted: (text) {
  664 +// print('submit $text');
  665 +// // 触发关闭弹出来的键盘。
  666 +// keyword = text;
  667 +// FocusScope.of(context).requestFocus(FocusNode());
  668 +// setState(() {
  669 +// // isloading = true;
  670 +// });
  671 +
  672 +// // _fetchInputTips(text.toString());
  673 +
  674 +// // searchAroundAddress(text.toString());
  675 +// },
  676 +// //按回车时调用
  677 +// onEditingComplete: () {
  678 +// print('onEditingComplete');
  679 +// },
  680 +// ),
  681 +// ),
  682 +// )
  683 +// ],
  684 +// ),
  685 +
  686 +// Expanded(
  687 +// flex: 1,
  688 +// child: Visibility(
  689 +// visible: !isloading,
  690 +// maintainSize: false,
  691 +// maintainSemantics: false,
  692 +// maintainInteractivity: false,
  693 +// replacement: Center(
  694 +// child: CupertinoActivityIndicator(),
  695 +// ),
  696 +// child: EasyRefresh.custom(
  697 +// controller: refreshController,
  698 +// slivers: [
  699 +// SliverList(
  700 +// delegate: SliverChildBuilderDelegate(
  701 +// (BuildContext context, int position) {
  702 +// print("itemBuilder" + list.length.toString());
  703 +// PoiModel item = list[position]!;
  704 +// return InkWell(
  705 +// child: Column(
  706 +// children: <Widget>[
  707 +// Container(
  708 +// margin: EdgeInsets.only(
  709 +// top: 8, bottom: 5, left: 10),
  710 +// child: Row(
  711 +// children: <Widget>[
  712 +// Icon(
  713 +// Icons.place,
  714 +// size: 20.0,
  715 +// color: position == 0
  716 +// ? Colors.green
  717 +// : Colors.grey,
  718 +// ),
  719 +// Expanded(
  720 +// child: Text(item.title,
  721 +// style: TextStyle(
  722 +// fontSize: 16,
  723 +// color: position == 0
  724 +// ? Colors.green
  725 +// : Color(0xFF787878))))
  726 +// ],
  727 +// ),
  728 +// ),
  729 +// Container(
  730 +// margin: EdgeInsets.only(
  731 +// top: 5, bottom: 5, left: 18),
  732 +// alignment: Alignment.centerLeft,
  733 +// child: Text(
  734 +// item.address!,
  735 +// style: TextStyle(
  736 +// fontSize: 14,
  737 +// color: Color(0xFF646464),
  738 +// ),
  739 +// ),
  740 +// ),
  741 +// Divider(
  742 +// height: 1,
  743 +// )
  744 +// ],
  745 +// ),
  746 +// onTap: () async {
  747 +// // await _controller.setCenterCoordinate(
  748 +// // LatLng(item.latLng.latitude, item.latLng.longitude),
  749 +// // zoomLevel: 16);
  750 +// if (Navigator.canPop(context)) {
  751 +// Navigator.pop(context, {
  752 +// 'address': item.address,
  753 +// 'lat': item.latLng!.latitude.toString(),
  754 +// 'lng': item.latLng!.longitude.toString()
  755 +// });
  756 +// }
  757 +// },
  758 +// );
  759 +// },
  760 +// childCount: list.length,
  761 +// ),
  762 +// )
  763 +// ],
  764 +// onRefresh: () async {
  765 +// if (flag) {
  766 +// page = 1;
  767 +// _loadData(LatLng(latitude, longitude));
  768 +// }
  769 +// },
  770 +// onLoad: () async {
  771 +// if (flag) {
  772 +// page++;
  773 +// _loadData(LatLng(latitude, longitude),
  774 +// showloading: false);
  775 +// }
  776 +// },
  777 +// )),
  778 +// ),
  779 +// ],
  780 +// ),
  781 +// );
  782 +// }
  783 +
  784 +// _fetchInputTips(String text) async {
  785 +// flag = false;
  786 +// page = 1;
  787 +// // setState(() {
  788 +// // isloading = true;
  789 +// // });
  790 +
  791 +// /// 逆地理编码(坐标转地址)
  792 +// ///
  793 +// ///
  794 +// // await AmapLocation.instance.updatePrivacyShow(true);
  795 +// // await AmapLocation.instance.updatePrivacyAgree(true);
  796 +
  797 +// LatLng latLng = LatLng(latitude, longitude);
  798 +
  799 +// address = await _locationPlugin
  800 +// .onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);
  801 +
  802 +// // await AmapLocation.instance.updatePrivacyShow(true);
  803 +// // await AmapLocation.instance.updatePrivacyAgree(true);
  804 +
  805 +// List<dynamic> temp = await _locationPlugin.doInputtipsRequest(
  806 +// text,
  807 +// city: "",
  808 +// );
  809 +
  810 +// inputTipDatas = [];
  811 +
  812 +// temp.forEach((element) {
  813 +// inputTipDatas.add(MapInputsModel.fromJson(element));
  814 +// });
  815 +
  816 +// print(inputTipDatas);
  817 +// poiModel = new PoiModel("当前位置", address, latLng);
  818 +// list.clear();
  819 +// list.add(poiModel);
  820 +// for (var inputTip in inputTipDatas) {
  821 +// String? title = await inputTip.name ?? '';
  822 +// String? cityStr = (inputTip.district ?? '') + (inputTip.city ?? '');
  823 +
  824 +// // LatLng? latLng = await inputTip.point;
  825 +
  826 +// list.add(new PoiModel(title.toString(), cityStr, latLng));
  827 +// }
  828 +
  829 +// print(list);
  830 +
  831 +// setState(() {
  832 +// // isloading = false;
  833 +// });
  834 +// }
  835 +
  836 +// void _loadData(LatLng latLng, {showloading = true}) async {
  837 +// flag = true;
  838 +// setState(() {
  839 +// if (showloading) {
  840 +// isloading = true;
  841 +// }
  842 +// });
  843 +
  844 +// /// 逆地理编码(坐标转地址)
  845 +// ///
  846 +// ///
  847 +// ///
  848 +
  849 +// // await AmapLocation.instance.updatePrivacyShow(true);
  850 +// // await AmapLocation.instance.updatePrivacyAgree(true);
  851 +// if (page == 1) {
  852 +// address = await _locationPlugin
  853 +// .onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);
  854 +// poiModel = new PoiModel("当前位置", address, latLng);
  855 +// list.clear();
  856 +// list.add(poiModel);
  857 +// }
  858 +// // final poiList
  859 +// List<dynamic> temp = await _locationPlugin.poiSearchAround(
  860 +// keyword, latLng.longitude, latLng.latitude);
  861 +
  862 +// List<MapRoundSearchModel> searchData = [];
  863 +
  864 +// temp.forEach((element) {
  865 +// searchData.add(MapRoundSearchModel.fromJson(element));
  866 +// });
  867 +
  868 +// print(searchData);
  869 +
  870 +// for (var poi in searchData) {
  871 +// String? title = await poi.title;
  872 +// String? cityName = await poi.cityName;
  873 +// String? provinceName = await poi.provinceName;
  874 +// String? snippet = await poi.snippet;
  875 +// String? adName = await poi.adName;
  876 +// LatLng? latLng = LatLng(poi.latitude ?? 0, poi.longitude ?? 0);
  877 +// String? bussniss = poi.businessArea;
  878 +
  879 +// list.add(new PoiModel(
  880 +// title.toString(),
  881 +// provinceName.toString() +
  882 +// cityName.toString() +
  883 +// adName.toString() +
  884 +// // address.toString() +
  885 +// bussniss.toString() +
  886 +// snippet.toString(),
  887 +// latLng));
  888 +// }
  889 +
  890 +// setState(() {
  891 +// if (showloading) {
  892 +// isloading = false;
  893 +// }
  894 +// });
  895 +// }
  896 +
  897 +// // void searchPoiId(String text) async {
  898 +// // await AmapLocation.instance.updatePrivacyShow(true);
  899 +// // await AmapLocation.instance.updatePrivacyAgree(true);
  900 +// // Poi? poi = await AmapSearch.instance.searchPoiId(
  901 +// // text,
  902 +// // );
  903 +// // print(poi);
  904 +// // }
  905 +
  906 +// // void searchAroundAddress(String text) async {
  907 +// // await AmapLocation.instance.updatePrivacyShow(true);
  908 +// // await AmapLocation.instance.updatePrivacyAgree(true);
  909 +// // final poiList = await AmapSearch.instance.searchKeyword(
  910 +// // text,
  911 +// // city: "",
  912 +// // );
  913 +// // // final poiList = await AmapSearch.instance.searchAround(
  914 +// // // LatLng(latitude, longitude),
  915 +// // // city: "",
  916 +// // // radius: 100000000000000
  917 +
  918 +// // // );
  919 +
  920 +// // list.clear();
  921 +// // list.add(poiModel);
  922 +// // for (var poi in poiList) {
  923 +// // String? title = await poi.title;
  924 +// // LatLng? latLng = await poi.latLng;
  925 +// // String? cityName = await poi.cityName;
  926 +// // String? provinceName = await poi.provinceName;
  927 +// // String? address = await poi.address;
  928 +// // list.add(new PoiModel(
  929 +// // title.toString(),
  930 +// // provinceName.toString() + cityName.toString() + address.toString(),
  931 +// // latLng));
  932 +// // }
  933 +// // setState(() {
  934 +// // isloading = false;
  935 +// // FocusScope.of(context).requestFocus(FocusNode());
  936 +// // });
  937 +// // }
  938 +// }
  939 +
  940 +// class PoiModel {
  941 +// LatLng? latLng;
  942 +// String title;
  943 +// String? address;
  944 +
  945 +// PoiModel(this.title, this.address, this.latLng);
  946 +// }
  1 +// import 'package:flutter/material.dart';
  2 +// import 'package:speech_to_text/speech_recognition_result.dart';
  3 +// import 'package:speech_to_text/speech_to_text.dart' as stt;
  4 +
  5 +
  6 +
  7 +
  8 +
  9 +// class MyTestPage extends StatefulWidget {
  10 +// MyTestPage({Key? key}) : super(key: key);
  11 +
  12 +// @override
  13 +// _MyTestPageState createState() => _MyTestPageState();
  14 +// }
  15 +
  16 +// class _MyTestPageState extends State<MyTestPage> {
  17 +// SpeechToText _speechToText = SpeechToText();
  18 +// bool _speechEnabled = false;
  19 +// String _lastWords = '';
  20 +
  21 +// @override
  22 +// void initState() {
  23 +// super.initState();
  24 +// _initSpeech();
  25 +// }
  26 +
  27 +// /// This has to happen only once per app
  28 +// void _initSpeech() async {
  29 +// _speechEnabled = await _speechToText.initialize();
  30 +// setState(() {});
  31 +// }
  32 +
  33 +// /// Each time to start a speech recognition session
  34 +// void _startListening() async {
  35 +// await _speechToText.listen(onResult: _onSpeechResult);
  36 +// setState(() {});
  37 +// }
  38 +
  39 +// /// Manually stop the active speech recognition session
  40 +// /// Note that there are also timeouts that each platform enforces
  41 +// /// and the SpeechToText plugin supports setting timeouts on the
  42 +// /// listen method.
  43 +// void _stopListening() async {
  44 +// await _speechToText.stop();
  45 +// setState(() {});
  46 +// }
  47 +
  48 +// /// This is the callback that the SpeechToText plugin calls when
  49 +// /// the platform returns recognized words.
  50 +// void _onSpeechResult(SpeechRecognitionResult result) {
  51 +// setState(() {
  52 +// _lastWords = result.recognizedWords;
  53 +// });
  54 +// }
  55 +
  56 +// @override
  57 +// Widget build(BuildContext context) {
  58 +// return Scaffold(
  59 +// appBar: AppBar(
  60 +// title: Text('Speech Demo'),
  61 +// ),
  62 +// body: Center(
  63 +// child: Column(
  64 +// mainAxisAlignment: MainAxisAlignment.center,
  65 +// children: <Widget>[
  66 +// Container(
  67 +// padding: EdgeInsets.all(16),
  68 +// child: Text(
  69 +// 'Recognized words:',
  70 +// style: TextStyle(fontSize: 20.0),
  71 +// ),
  72 +// ),
  73 +// Expanded(
  74 +// child: Container(
  75 +// padding: EdgeInsets.all(16),
  76 +// child: Text(
  77 +// // If listening is active show the recognized words
  78 +// _speechToText.isListening
  79 +// ? '$_lastWords'
  80 +// // If listening isn't active but could be tell the user
  81 +// // how to start it, otherwise indicate that speech
  82 +// // recognition is not yet ready or not supported on
  83 +// // the target device
  84 +// : _speechEnabled
  85 +// ? 'Tap the microphone to start listening...'
  86 +// : 'Speech not available',
  87 +// ),
  88 +// ),
  89 +// ),
  90 +// ],
  91 +// ),
  92 +// ),
  93 +// floatingActionButton: FloatingActionButton(
  94 +// onPressed:
  95 +// // If not yet listening for speech start, otherwise stop
  96 +// _speechToText.isNotListening ? _startListening : _stopListening,
  97 +// tooltip: 'Listen',
  98 +// child: Icon(_speechToText.isNotListening ? Icons.mic_off : Icons.mic),
  99 +// ),
  100 +// );
  101 +// }
  102 +// }
  1 +// import 'dart:async';
  2 +
  3 +// import 'package:flutter/material.dart';
  4 +// import 'package:one_key/pages/home/RecognitionResultsWidget.dart';
  5 +// import 'package:provider/provider.dart';
  6 +// import 'package:speech_to_text/speech_to_text.dart';
  7 +// import 'package:speech_to_text/speech_to_text_provider.dart';
  8 +
  9 +// class ProviderDemoApp extends StatefulWidget {
  10 +// const ProviderDemoApp({super.key});
  11 +
  12 +// @override
  13 +// State<ProviderDemoApp> createState() => _ProviderDemoAppState();
  14 +// }
  15 +
  16 +// class _ProviderDemoAppState extends State<ProviderDemoApp> {
  17 +// final SpeechToText speech = SpeechToText();
  18 +// late SpeechToTextProvider speechProvider;
  19 +
  20 +// @override
  21 +// void initState() {
  22 +// super.initState();
  23 +// speechProvider = SpeechToTextProvider(speech);
  24 +// initSpeechState();
  25 +// }
  26 +
  27 +// Future<void> initSpeechState() async {
  28 +// bool ggggg = await speechProvider.initialize();
  29 +// print(ggggg);
  30 +// }
  31 +
  32 +// @override
  33 +// Widget build(BuildContext context) {
  34 +// return ChangeNotifierProvider<SpeechToTextProvider>.value(
  35 +// value: speechProvider,
  36 +// child: MaterialApp(
  37 +// home: Scaffold(
  38 +// appBar: AppBar(
  39 +// title: const Text('标题'),
  40 +// ),
  41 +// body: const SpeechProviderExampleWidget(),
  42 +// ),
  43 +// ),
  44 +// );
  45 +// }
  46 +// }
  47 +
  48 +// class SpeechProviderExampleWidget extends StatefulWidget {
  49 +// const SpeechProviderExampleWidget({super.key});
  50 +
  51 +// @override
  52 +// SpeechProviderExampleWidgetState createState() =>
  53 +// SpeechProviderExampleWidgetState();
  54 +// }
  55 +
  56 +// class SpeechProviderExampleWidgetState
  57 +// extends State<SpeechProviderExampleWidget> {
  58 +// String _currentLocaleId = '';
  59 +
  60 +// void _setCurrentLocale(SpeechToTextProvider speechProvider) {
  61 +// if (speechProvider.isAvailable && _currentLocaleId.isEmpty) {
  62 +// _currentLocaleId = speechProvider.systemLocale?.localeId ?? '';
  63 +// }
  64 +// }
  65 +
  66 +// @override
  67 +// Widget build(BuildContext context) {
  68 +// var speechProvider = Provider.of<SpeechToTextProvider>(context);
  69 +// if (speechProvider.isNotAvailable) {
  70 +// return const Center(
  71 +// child: Text(
  72 +// 'Speech recognition not available, no permission or not available on the device.'),
  73 +// );
  74 +// }
  75 +// _setCurrentLocale(speechProvider);
  76 +// return Column(children: [
  77 +// const Center(
  78 +// child: Text(
  79 +// 'Speech recognition available',
  80 +// style: TextStyle(fontSize: 22.0),
  81 +// ),
  82 +// ),
  83 +// Column(
  84 +// children: <Widget>[
  85 +// Row(
  86 +// mainAxisAlignment: MainAxisAlignment.spaceAround,
  87 +// children: <Widget>[
  88 +// TextButton(
  89 +// onPressed:
  90 +// !speechProvider.isAvailable || speechProvider.isListening
  91 +// ? null
  92 +// : () => speechProvider.listen(
  93 +// partialResults: true, localeId: _currentLocaleId),
  94 +// child: const Text('Start'),
  95 +// ),
  96 +// TextButton(
  97 +// onPressed: speechProvider.isListening
  98 +// ? () => speechProvider.stop()
  99 +// : null,
  100 +// child: const Text('Stop'),
  101 +// ),
  102 +// TextButton(
  103 +// onPressed: speechProvider.isListening
  104 +// ? () => speechProvider.cancel()
  105 +// : null,
  106 +// child: const Text('Cancel'),
  107 +// ),
  108 +// ],
  109 +// ),
  110 +// Row(
  111 +// mainAxisAlignment: MainAxisAlignment.spaceAround,
  112 +// children: <Widget>[
  113 +// DropdownButton(
  114 +// onChanged: (selectedVal) => _switchLang(selectedVal),
  115 +// value: _currentLocaleId,
  116 +// items: speechProvider.locales
  117 +// .map(
  118 +// (localeName) => DropdownMenuItem(
  119 +// value: localeName.localeId,
  120 +// child: Text(localeName.name),
  121 +// ),
  122 +// )
  123 +// .toList(),
  124 +// ),
  125 +// ],
  126 +// )
  127 +// ],
  128 +// ),
  129 +// const Expanded(
  130 +// flex: 4,
  131 +// child: RecognitionResultsWidget(),
  132 +// ),
  133 +// Expanded(
  134 +// flex: 1,
  135 +// child: Column(
  136 +// children: <Widget>[
  137 +// const Center(
  138 +// child: Text(
  139 +// 'Error Status',
  140 +// style: TextStyle(fontSize: 22.0),
  141 +// ),
  142 +// ),
  143 +// Center(
  144 +// child: speechProvider.hasError
  145 +// ? Text(speechProvider.lastError!.errorMsg)
  146 +// : Container(),
  147 +// ),
  148 +// ],
  149 +// ),
  150 +// ),
  151 +// Container(
  152 +// padding: const EdgeInsets.symmetric(vertical: 20),
  153 +// color: Theme.of(context).colorScheme.surface,
  154 +// child: Center(
  155 +// child: speechProvider.isListening
  156 +// ? const Text(
  157 +// "I'm listening...",
  158 +// style: TextStyle(fontWeight: FontWeight.bold),
  159 +// )
  160 +// : const Text(
  161 +// 'Not listening',
  162 +// style: TextStyle(fontWeight: FontWeight.bold),
  163 +// ),
  164 +// ),
  165 +// ),
  166 +// ]);
  167 +// }
  168 +
  169 +// void _switchLang(selectedVal) {
  170 +// setState(() {
  171 +// _currentLocaleId = selectedVal;
  172 +// });
  173 +// debugPrint(selectedVal);
  174 +// }
  175 +// }
  1 +// import 'package:flutter/material.dart';
  2 +// import 'package:provider/provider.dart';
  3 +// import 'package:speech_to_text/speech_to_text_provider.dart';
  4 +
  5 +// /// Show the most recently recognized speech results and use the level
  6 +// /// information to animate the microphone.
  7 +// ///
  8 +// /// Note that the provider is initialized elsewhere and just accessed
  9 +// /// here.
  10 +// class RecognitionResultsWidget extends StatelessWidget {
  11 +// const RecognitionResultsWidget({super.key});
  12 +
  13 +// @override
  14 +// Widget build(BuildContext context) {
  15 +// var speechProvider = Provider.of<SpeechToTextProvider>(context);
  16 +// return Column(
  17 +// children: <Widget>[
  18 +// const Center(
  19 +// child: Text(
  20 +// 'Recognized Words',
  21 +// style: TextStyle(fontSize: 22.0),
  22 +// ),
  23 +// ),
  24 +// Expanded(
  25 +// child: Stack(
  26 +// children: <Widget>[
  27 +// Container(
  28 +// color: Theme.of(context).secondaryHeaderColor,
  29 +// child: Center(
  30 +// child: Text(
  31 +// speechProvider.lastResult?.recognizedWords ?? '',
  32 +// textAlign: TextAlign.center,
  33 +// ),
  34 +// ),
  35 +// ),
  36 +// Positioned.fill(
  37 +// bottom: 10,
  38 +// child: Align(
  39 +// alignment: Alignment.bottomCenter,
  40 +// child: Container(
  41 +// width: 40,
  42 +// height: 40,
  43 +// alignment: Alignment.center,
  44 +// decoration: BoxDecoration(
  45 +// boxShadow: [
  46 +// BoxShadow(
  47 +// blurRadius: .26,
  48 +// spreadRadius: speechProvider.lastLevel * 1.5,
  49 +// color: Colors.black.withOpacity(.05))
  50 +// ],
  51 +// color: Colors.white,
  52 +// borderRadius: const BorderRadius.all(Radius.circular(50)),
  53 +// ),
  54 +// child: IconButton(
  55 +// icon: const Icon(Icons.mic),
  56 +// onPressed: () {},
  57 +// ),
  58 +// ),
  59 +// ),
  60 +// ),
  61 +// ],
  62 +// ),
  63 +// ),
  64 +// ],
  65 +// );
  66 +// }
  67 +// }
  1 +/*
  2 + * Copyright 2018, 2019, 2020, 2021 Dooboolab.
  3 + *
  4 + * This file is part of Flutter-Sound.
  5 + *
  6 + * Flutter-Sound is free software: you can redistribute it and/or modify
  7 + * it under the terms of the Mozilla Public License version 2 (MPL2.0),
  8 + * as published by the Mozilla organization.
  9 + *
  10 + * Flutter-Sound is distributed in the hope that it will be useful,
  11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13 + * MPL General Public License for more details.
  14 + *
  15 + * This Source Code Form is subject to the terms of the Mozilla Public
  16 + * License, v. 2.0. If a copy of the MPL was not distributed with this
  17 + * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  18 + */
  19 +
  20 +import 'dart:async';
  21 +import 'dart:io';
  22 +import 'dart:math';
  23 +import 'dart:typed_data' show Uint8List;
  24 +
  25 +import 'package:audio_session/audio_session.dart';
  26 +import 'package:flutter/material.dart';
  27 +import 'package:path_provider/path_provider.dart';
  28 +import 'package:flutter/services.dart' show rootBundle;
  29 +import 'package:intl/date_symbol_data_local.dart';
  30 +import 'package:intl/intl.dart' show DateFormat;
  31 +import 'package:flutter_sound/flutter_sound.dart';
  32 +import 'package:permission_handler/permission_handler.dart';
  33 +import 'package:flutter/foundation.dart' show kIsWeb;
  34 +import 'dart:typed_data';
  35 +
  36 +/*
  37 +
  38 +This is a demo of what it is possible to do with Flutter Sound. The code of this demo app is not so simple.
  39 +
  40 +Flutter Sound beginners : you probably should look to [SimplePlayback](fs-ex_simple_playback.html)
  41 +and [SimpleRecorder](fs-ex_simple_recorder.html)
  42 +
  43 +The biggest interest of this Demo is that it shows most of the features of Flutter Sound :
  44 +
  45 +* Plays from various media with various codecs
  46 +* Records to various media with various codecs
  47 +* Pause and Resume control from recording or playback
  48 +* Shows how to use a stream for getting the playback \(or recoding\) events
  49 +* Shows how to specify a callback function when a playback is terminated,
  50 +* Shows how to record to a Stream or playback from a stream
  51 +* ...
  52 +
  53 + */
  54 +///
  55 +const int cstSAMPLERATE = 8000;
  56 +const int cstCHANNELNB = 2;
  57 +const int cstBITRATE = 16000;
  58 +
  59 +///
  60 +const int cstBLOCKSIZE = 4096;
  61 +
  62 +///
  63 +enum Media {
  64 + ///
  65 + file,
  66 +
  67 + ///
  68 + buffer,
  69 +
  70 + ///
  71 + asset,
  72 +
  73 + ///
  74 + stream,
  75 +
  76 + ///
  77 + remoteExampleFile,
  78 +}
  79 +
  80 +///
  81 +enum AudioState {
  82 + ///
  83 + isPlaying,
  84 +
  85 + ///
  86 + isPaused,
  87 +
  88 + ///
  89 + isStopped,
  90 +
  91 + ///
  92 + isRecording,
  93 +
  94 + ///
  95 + isRecordingPaused,
  96 +}
  97 +
  98 +/*
  99 +///
  100 +final exampleAudioFilePathAACAdts =
  101 + //'https://filesamples.com/samples/audio/aac/sample1.aac';
  102 + 'https://www.canardoux.xyz/tau_sound/web_example/sample.aac';
  103 +
  104 +///
  105 +final exampleAudioFilePathWave =
  106 + 'http://5.189.150.137:5000/download_audio/CantinaBand3.wav';
  107 +
  108 +///
  109 +final exampleAudioFilePathMP3 =
  110 + 'https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3';
  111 +
  112 +///
  113 +final exampleAudioFilePathOPUS =
  114 + 'https://whatsapp-inbox-server.clare.ai/api/file/showFile?fileName=data/audios/e3f16eb2-10c3-45c9-b0fa-900c94cbe805.opus&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMWI5YjQ3Zi1jMzBjLTRlZDMtYTFhNy1iNmYxNzRkMWQ1NTYiLCJ1bmlxdWVfbmFtZSI6InZlcm5hbEBjbGFyZS5haSIsIm5hbWVpZCI6InZlcm5hbEBjbGFyZS5haSIsImVtYWlsIjoidmVybmFsQGNsYXJlLmFpIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiRVhURVJOQUxfQURNSU5JU1RSQVRPUiIsImV4cCI6MjUzNDAyMzAwODAwLCJpc3MiOiJDbGFyZV9BSSIsImF1ZCI6IkNsYXJlX0FJIn0.yXVZ3n_lYYvJ1rGyF2mVh-80HuS0EEp7sQepxn9rGcY';
  115 +///
  116 +final albumArtPath =
  117 + 'https://file-examples-com.github.io/uploads/2017/10/file_example_PNG_500kB.png';
  118 +*/
  119 +const albumArtPathRemote =
  120 + 'https://flutter-sound.canardoux.xyz/web_example/assets/extract/3iob.png';
  121 +const albumArtPath =
  122 + 'https://file-examples-com.github.io/uploads/2017/10/file_example_PNG_500kB.png';
  123 +
  124 +///
  125 +class Demo extends StatefulWidget {
  126 + const Demo({super.key});
  127 + @override
  128 + State<Demo> createState() => _MyAppState();
  129 +}
  130 +
  131 +class _MyAppState extends State<Demo> {
  132 + bool _isRecording = false;
  133 + final List<String?> _path = [
  134 + null,
  135 + null,
  136 + null,
  137 + null,
  138 + null,
  139 + null,
  140 + null,
  141 + null,
  142 + null,
  143 + null,
  144 + null,
  145 + null,
  146 + null,
  147 + null,
  148 + null,
  149 + null,
  150 + null,
  151 + null,
  152 + null,
  153 + null,
  154 + ];
  155 +
  156 + List<String> assetSample = [
  157 + 'assets/samples/sample.aac',
  158 + 'assets/samples/sample.aac',
  159 + 'assets/samples/sample.opus',
  160 + 'assets/samples/sample_opus.caf',
  161 + 'assets/samples/sample.mp3',
  162 + 'assets/samples/sample.ogg',
  163 + 'assets/samples/sample_s16_2ch.raw', // Raw PCM int16
  164 + 'assets/samples/sample_2ch.wav', // int16 wav stereo
  165 + 'assets/samples/sample.aiff',
  166 + 'assets/samples/sample_pcm.caf',
  167 + 'assets/samples/sample.flac',
  168 + 'assets/samples/sample.mp4',
  169 + 'assets/samples/sample.amr', // amrNB
  170 + 'assets/samples/sample_xxx.amr', // amrWB
  171 + 'assets/samples/sample_xxx.pcm', // pcm8
  172 + 'assets/samples/sample_f32_2ch.raw', // Raw pcmFloat32
  173 + '', // 'assets/samples/sample_xxx.pcm', // pcmWebM
  174 + 'assets/samples/sample_opus.webm', // opusWebM
  175 + 'assets/samples/sample_vorbis.webm', // vorbisWebM
  176 + 'assets/samples/sample_f32_2ch.wav', // wav Float32 stereo
  177 + ];
  178 +
  179 + List<String> remoteSample = [
  180 + 'https://fs-doc.vercel.app/extract/01.aac', // 'assets/samples/sample.aac',
  181 + 'https://fs-doc.vercel.app/extract/01.aac', // 'assets/samples/sample.aac',
  182 + 'https://fs-doc.vercel.app/extract/08.opus', // 'assets/samples/sample.opus',
  183 + 'https://fs-doc.vercel.app/extract/04-opus.caf', // 'assets/samples/sample_opus.caf',
  184 + 'https://fs-doc.vercel.app/extract/05.mp3', // 'assets/samples/sample.mp3',
  185 + 'https://fs-doc.vercel.app/extract/07.ogg', // 'assets/samples/sample.ogg',
  186 + 'https://fs-doc.vercel.app/extract/sample_s16_2ch.pcm', // Raw PCM int16
  187 + 'https://fs-doc.vercel.app/extract/sample_2ch.wav', // int16 wav stereo
  188 + 'https://fs-doc.vercel.app/extract/02.aiff', // 'assets/samples/sample.aiff',
  189 + 'https://fs-doc.vercel.app/extract/01-pcm.caf', // 'assets/samples/sample_pcm.caf',
  190 + 'https://fs-doc.vercel.app/extract/04.flac', // 'assets/samples/sample.flac',
  191 + 'https://fs-doc.vercel.app/extract/06.mp4', // 'assets/samples/sample.mp4',
  192 + 'https://fs-doc.vercel.app/extract/03.amr', // 'assets/samples/sample.amr', // amrNB
  193 + 'https://fs-doc.vercel.app/extract/03.amr', // 'assets/samples/sample_xxx.amr', // amrWB
  194 + 'https://fs-doc.vercel.app/extract/09-pcm8.raw', // 'assets/samples/sample_xxx.pcm', // pcm8
  195 + 'https://fs-doc.vercel.app/extract/sample_f32_2ch.raw', // Raw pcmFloat32
  196 + '', // pcmWebM
  197 + 'https://fs-doc.vercel.app/extract/02-opus.webm', // 'assets/samples/sample_opus.webm', // opusWebM
  198 + 'https://fs-doc.vercel.app/extract/03-vorbis.webm', // 'assets/samples/sample_vorbis.webm', // vorbisWebM
  199 + 'https://fs-doc.vercel.app/extract/sample_f32_2ch.wav', // wav Float32 stereo
  200 + ];
  201 +
  202 + StreamSubscription? _recorderSubscription;
  203 + StreamSubscription? _playerSubscription;
  204 + StreamSubscription? _recordingDataSubscription;
  205 +
  206 + FlutterSoundPlayer playerModule = FlutterSoundPlayer();
  207 + FlutterSoundRecorder recorderModule = FlutterSoundRecorder();
  208 +
  209 + String _recorderTxt = '00:00:00';
  210 + String _playerTxt = '00:00:00';
  211 + double? _dbLevel;
  212 +
  213 + double sliderCurrentPosition = 0.0;
  214 + double maxDuration = 1.0;
  215 + Media? _media = Media.remoteExampleFile;
  216 + Codec _codec = Codec.aacMP4;
  217 +
  218 + bool? _encoderSupported = true; // Optimist
  219 + bool _decoderSupported = true; // Optimist
  220 +
  221 + StreamController<Uint8List>? recordingDataController;
  222 + IOSink? sink;
  223 +
  224 + Future<void> _initializeExample() async {
  225 + await playerModule.closePlayer();
  226 + await playerModule.openPlayer();
  227 + await playerModule
  228 + .setSubscriptionDuration(const Duration(milliseconds: 10));
  229 + await recorderModule
  230 + .setSubscriptionDuration(const Duration(milliseconds: 100));
  231 + await initializeDateFormatting();
  232 + await setCodec(_codec);
  233 + }
  234 +
  235 + Future<void> openTheRecorder() async {
  236 + if (!kIsWeb) {
  237 + var status = await Permission.microphone.request();
  238 + if (status != PermissionStatus.granted) {
  239 + throw RecordingPermissionException('Microphone permission not granted');
  240 + }
  241 + }
  242 + await recorderModule.openRecorder();
  243 +
  244 + if (!await recorderModule.isEncoderSupported(_codec) && kIsWeb) {
  245 + _codec = Codec.opusWebM;
  246 + }
  247 + }
  248 +
  249 + Future<void> init() async {
  250 + await openTheRecorder();
  251 + await _initializeExample();
  252 +
  253 + if ((!kIsWeb) && Platform.isAndroid) {
  254 + await copyAssets();
  255 + }
  256 +
  257 + final session = await AudioSession.instance;
  258 + await session.configure(AudioSessionConfiguration(
  259 + avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
  260 + avAudioSessionCategoryOptions:
  261 + AVAudioSessionCategoryOptions.allowBluetooth |
  262 + AVAudioSessionCategoryOptions.defaultToSpeaker,
  263 + avAudioSessionMode: AVAudioSessionMode.spokenAudio,
  264 + avAudioSessionRouteSharingPolicy:
  265 + AVAudioSessionRouteSharingPolicy.defaultPolicy,
  266 + avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
  267 + androidAudioAttributes: const AndroidAudioAttributes(
  268 + contentType: AndroidAudioContentType.speech,
  269 + flags: AndroidAudioFlags.none,
  270 + usage: AndroidAudioUsage.voiceCommunication,
  271 + ),
  272 + androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
  273 + androidWillPauseWhenDucked: true,
  274 + ));
  275 + }
  276 +
  277 + Future<void> copyAssets() async {
  278 + var dataBuffer =
  279 + (await rootBundle.load('assets/canardo.png')).buffer.asUint8List();
  280 + var path = '${await playerModule.getResourcePath()}/assets';
  281 + if (!await Directory(path).exists()) {
  282 + await Directory(path).create(recursive: true);
  283 + }
  284 + await File('$path/canardo.png').writeAsBytes(dataBuffer);
  285 + }
  286 +
  287 + @override
  288 + void initState() {
  289 + super.initState();
  290 + init();
  291 + }
  292 +
  293 + void cancelRecorderSubscriptions() {
  294 + if (_recorderSubscription != null) {
  295 + _recorderSubscription!.cancel();
  296 + _recorderSubscription = null;
  297 + }
  298 + }
  299 +
  300 + void cancelPlayerSubscriptions() {
  301 + if (_playerSubscription != null) {
  302 + _playerSubscription!.cancel();
  303 + _playerSubscription = null;
  304 + }
  305 + }
  306 +
  307 + void cancelRecordingDataSubscription() {
  308 + if (_recordingDataSubscription != null) {
  309 + _recordingDataSubscription!.cancel();
  310 + _recordingDataSubscription = null;
  311 + }
  312 + recordingDataController = null;
  313 + if (sink != null) {
  314 + sink!.close();
  315 + sink = null;
  316 + }
  317 + }
  318 +
  319 + @override
  320 + void dispose() {
  321 + super.dispose();
  322 + cancelPlayerSubscriptions();
  323 + cancelRecorderSubscriptions();
  324 + cancelRecordingDataSubscription();
  325 + releaseFlauto();
  326 + }
  327 +
  328 + Future<void> releaseFlauto() async {
  329 + try {
  330 + await playerModule.closePlayer();
  331 + await recorderModule.closeRecorder();
  332 + } on Exception {
  333 + playerModule.logger.e('Released unsuccessful');
  334 + }
  335 + }
  336 +
  337 + void startRecorder() async {
  338 + try {
  339 + // Request Microphone permission if needed
  340 + if (!kIsWeb) {
  341 + var status = await Permission.microphone.request();
  342 + if (status != PermissionStatus.granted) {
  343 + throw RecordingPermissionException(
  344 + 'Microphone permission not granted');
  345 + }
  346 + }
  347 + var path = '';
  348 + if (!kIsWeb) {
  349 + var tempDir = await getTemporaryDirectory();
  350 + path = '${tempDir.path}/flutter_sound${ext[_codec.index]}';
  351 + } else {
  352 + path = '_flutter_sound${ext[_codec.index]}';
  353 + }
  354 +
  355 + if (_media == Media.stream) {
  356 + assert(_codec == Codec.pcm16);
  357 + if (!kIsWeb) {
  358 + var outputFile = File(path);
  359 + if (outputFile.existsSync()) {
  360 + await outputFile.delete();
  361 + }
  362 + sink = outputFile.openWrite();
  363 + } else {
  364 + sink = null; // TODO
  365 + }
  366 + recordingDataController = StreamController<Uint8List>();
  367 + _recordingDataSubscription =
  368 + recordingDataController!.stream.listen((buffer) {
  369 + sink!.add(buffer);
  370 + });
  371 + await recorderModule.startRecorder(
  372 + toStream: recordingDataController!.sink,
  373 + bufferSize: 128,
  374 + codec: _codec,
  375 + numChannels: cstCHANNELNB,
  376 + sampleRate: cstSAMPLERATE, // tSTREAMSAMPLERATE, //tSAMPLERATE,
  377 + );
  378 + } else {
  379 + await recorderModule.startRecorder(
  380 + toFile: path,
  381 + codec: _codec,
  382 + bitRate: cstBITRATE,
  383 + numChannels: cstCHANNELNB,
  384 + sampleRate:
  385 + cstSAMPLERATE, // (_codec == Codec.pcm16) ? tSTREAMSAMPLERATE : tSAMPLERATE,
  386 + );
  387 + }
  388 + recorderModule.logger.d('startRecorder');
  389 +
  390 + _recorderSubscription = recorderModule.onProgress!.listen((e) {
  391 + var date = DateTime.fromMillisecondsSinceEpoch(
  392 + e.duration.inMilliseconds,
  393 + isUtc: true);
  394 + var txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
  395 +
  396 + setState(() {
  397 + _recorderTxt = txt.substring(0, 8);
  398 + _dbLevel = e.decibels;
  399 + });
  400 + });
  401 +
  402 + setState(() {
  403 + _isRecording = true;
  404 + _path[_codec.index] = path;
  405 + });
  406 + } on Exception catch (err) {
  407 + recorderModule.logger.e('startRecorder error: $err');
  408 + setState(() {
  409 + stopRecorder();
  410 + _isRecording = false;
  411 + cancelRecordingDataSubscription();
  412 + cancelRecorderSubscriptions();
  413 + });
  414 + }
  415 + }
  416 +
  417 + void stopRecorder() async {
  418 + try {
  419 + await recorderModule.stopRecorder();
  420 + recorderModule.logger.d('stopRecorder');
  421 + cancelRecorderSubscriptions();
  422 + cancelRecordingDataSubscription();
  423 + } on Exception catch (err) {
  424 + recorderModule.logger.d('stopRecorder error: $err');
  425 + }
  426 + setState(() {
  427 + _isRecording = false;
  428 + });
  429 + }
  430 +
  431 + Future<bool> fileExists(String path) async {
  432 + return await File(path).exists();
  433 + }
  434 +
  435 + // In this simple example, we just load a file in memory.This is stupid but just for demonstration of startPlayerFromBuffer()
  436 + Future<Uint8List?> makeBuffer(String path) async {
  437 + try {
  438 + if (!await fileExists(path)) return null;
  439 + var file = File(path);
  440 + file.openRead();
  441 + var contents = await file.readAsBytes();
  442 + playerModule.logger.i('The file is ${contents.length} bytes long.');
  443 + return contents;
  444 + } on Exception catch (e) {
  445 + playerModule.logger.e(e);
  446 + return null;
  447 + }
  448 + }
  449 +
  450 + void _addListeners() {
  451 + cancelPlayerSubscriptions();
  452 + _playerSubscription = playerModule.onProgress!.listen((e) {
  453 + maxDuration = e.duration.inMilliseconds.toDouble();
  454 + if (maxDuration <= 0) maxDuration = 0.0;
  455 +
  456 + sliderCurrentPosition =
  457 + min(e.position.inMilliseconds.toDouble(), maxDuration);
  458 + if (sliderCurrentPosition < 0.0) {
  459 + sliderCurrentPosition = 0.0;
  460 + }
  461 +
  462 + var date = DateTime.fromMillisecondsSinceEpoch(e.position.inMilliseconds,
  463 + isUtc: true);
  464 + var txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
  465 + setState(() {
  466 + _playerTxt = txt.substring(0, 8);
  467 + });
  468 + });
  469 + }
  470 +
  471 + Future<Uint8List> _readFileByte(String filePath) async {
  472 + var myUri = Uri.parse(filePath);
  473 + var audioFile = File.fromUri(myUri);
  474 + Uint8List bytes;
  475 + var b = await audioFile.readAsBytes();
  476 + bytes = Uint8List.fromList(b);
  477 + playerModule.logger.d('reading of bytes is completed');
  478 + return bytes;
  479 + }
  480 +
  481 + Future<Uint8List> getAssetData(String path) async {
  482 + var asset = await rootBundle.load(path);
  483 + return asset.buffer.asUint8List();
  484 + }
  485 +
  486 + /*
  487 + Future<void> feedHim(String path) async {
  488 + var data = await _readFileByte(path);
  489 + return await playerModule.feedFromStream(data);
  490 + }
  491 +*/
  492 +
  493 + final int blockSize = 4096;
  494 + Future<void> feedHim(String path) async {
  495 + var buffer = await _readFileByte(path);
  496 + //var buffer = await getAssetData('assets/samples/sample.pcm');
  497 +
  498 + var lnData = 0;
  499 + var totalLength = buffer.length;
  500 + while (totalLength > 0 && !playerModule.isStopped) {
  501 + var bsize = totalLength > blockSize ? blockSize : totalLength;
  502 + await playerModule.feedUint8FromStream(
  503 + buffer.sublist(lnData, lnData + bsize)); // await !!!!
  504 + lnData += bsize;
  505 + totalLength -= bsize;
  506 + }
  507 + }
  508 +
  509 + Future<void> startPlayer() async {
  510 + try {
  511 + Uint8List? dataBuffer;
  512 + String? audioFilePath;
  513 + var codec = _codec;
  514 + if (_media == Media.asset) {
  515 + dataBuffer = (await rootBundle.load(assetSample[codec.index]))
  516 + .buffer
  517 + .asUint8List();
  518 + } else if (_media == Media.file || _media == Media.stream) {
  519 + // Do we want to play from buffer or from file ?
  520 + if (kIsWeb || await fileExists(_path[codec.index]!)) {
  521 + audioFilePath = _path[codec.index];
  522 + }
  523 + } else if (_media == Media.buffer) {
  524 + // Do we want to play from buffer or from file ?
  525 + if (await fileExists(_path[codec.index]!)) {
  526 + dataBuffer = await makeBuffer(_path[codec.index]!);
  527 + if (dataBuffer == null) {
  528 + throw Exception('Unable to create the buffer');
  529 + }
  530 + }
  531 + } else if (_media == Media.remoteExampleFile) {
  532 + // We have to play an example audio file loaded via a URL
  533 + audioFilePath = remoteSample[_codec.index];
  534 + }
  535 +
  536 + if (_media == Media.stream) {
  537 + await playerModule.startPlayerFromStream(
  538 + codec: Codec.pcm16, //_codec,
  539 + numChannels: cstCHANNELNB,
  540 + sampleRate: cstSAMPLERATE, // tSTREAMSAMPLERATE, //tSAMPLERATE,
  541 + interleaved: true,
  542 + bufferSize: 1024,
  543 + );
  544 + _addListeners();
  545 + setState(() {});
  546 + await feedHim(audioFilePath!);
  547 + //await finishPlayer();
  548 + await stopPlayer();
  549 + return;
  550 + } else {
  551 + if (audioFilePath != null) {
  552 + await playerModule.startPlayer(
  553 + fromURI: audioFilePath,
  554 + codec: codec,
  555 + numChannels: cstCHANNELNB,
  556 + sampleRate: cstSAMPLERATE, // tSTREAMSAMPLERATE,
  557 + whenFinished: () {
  558 + playerModule.logger.d('Play finished');
  559 + setState(() {});
  560 + });
  561 + } else if (dataBuffer != null) {
  562 + if (codec == Codec.pcm16) {
  563 + dataBuffer = await flutterSoundHelper.pcmToWaveBuffer(
  564 + inputBuffer: dataBuffer,
  565 + numChannels: cstCHANNELNB,
  566 + sampleRate:
  567 + cstSAMPLERATE, //(_codec == Codec.pcm16 && _media == Media.asset) ? 48000 : cstSAMPLERATE,
  568 + );
  569 + codec = Codec.pcm16WAV;
  570 + }
  571 + await playerModule.startPlayer(
  572 + fromDataBuffer: dataBuffer,
  573 + sampleRate: cstSAMPLERATE,
  574 + numChannels: cstCHANNELNB,
  575 + codec: codec,
  576 + whenFinished: () {
  577 + playerModule.logger.d('Play finished');
  578 + setState(() {});
  579 + });
  580 + }
  581 + }
  582 + _addListeners();
  583 + setState(() {});
  584 + playerModule.logger.d('<--- startPlayer');
  585 + } on Exception catch (err) {
  586 + playerModule.logger.e('error: $err');
  587 + await stopPlayer();
  588 + }
  589 + }
  590 +
  591 + Future<void> stopPlayer() async {
  592 + try {
  593 + await playerModule.stopPlayer();
  594 + playerModule.logger.d('stopPlayer');
  595 + if (_playerSubscription != null) {
  596 + await _playerSubscription!.cancel();
  597 + _playerSubscription = null;
  598 + }
  599 + sliderCurrentPosition = 0.0;
  600 + } on Exception catch (err) {
  601 + playerModule.logger.d('error: $err');
  602 + }
  603 + setState(() {});
  604 + }
  605 +
  606 + void pauseResumePlayer() async {
  607 + try {
  608 + if (playerModule.isPlaying) {
  609 + await playerModule.pausePlayer();
  610 + } else {
  611 + await playerModule.resumePlayer();
  612 + }
  613 + } on Exception catch (err) {
  614 + playerModule.logger.e('error: $err');
  615 + }
  616 + setState(() {});
  617 + }
  618 +
  619 + void pauseResumeRecorder() async {
  620 + try {
  621 + if (recorderModule.isPaused) {
  622 + await recorderModule.resumeRecorder();
  623 + } else {
  624 + await recorderModule.pauseRecorder();
  625 + assert(recorderModule.isPaused);
  626 + }
  627 + } on Exception catch (err) {
  628 + recorderModule.logger.e('error: $err');
  629 + }
  630 + setState(() {});
  631 + }
  632 +
  633 + Future<void> seekToPlayer(int milliSecs) async {
  634 + //playerModule.logger.d('-->seekToPlayer');
  635 + try {
  636 + if (playerModule.isPlaying) {
  637 + await playerModule.seekToPlayer(Duration(milliseconds: milliSecs));
  638 + }
  639 + } on Exception catch (err) {
  640 + playerModule.logger.e('error: $err');
  641 + }
  642 + setState(() {});
  643 + //playerModule.logger.d('<--seekToPlayer');
  644 + }
  645 +
  646 + Widget makeDropdowns(BuildContext context) {
  647 + final mediaDropdown = Row(
  648 + mainAxisAlignment: MainAxisAlignment.start,
  649 + crossAxisAlignment: CrossAxisAlignment.center,
  650 + children: <Widget>[
  651 + const Padding(
  652 + padding: EdgeInsets.only(right: 16.0),
  653 + child: Text('Media:'),
  654 + ),
  655 + DropdownButton<Media>(
  656 + value: _media,
  657 + onChanged: (newMedia) {
  658 + _media = newMedia;
  659 + setState(() {});
  660 + },
  661 + items: const <DropdownMenuItem<Media>>[
  662 + DropdownMenuItem<Media>(
  663 + value: Media.file,
  664 + child: Text('File'),
  665 + ),
  666 + DropdownMenuItem<Media>(
  667 + value: Media.buffer,
  668 + child: Text('Buffer'),
  669 + ),
  670 + DropdownMenuItem<Media>(
  671 + value: Media.asset,
  672 + child: Text('Asset'),
  673 + ),
  674 + DropdownMenuItem<Media>(
  675 + value: Media.remoteExampleFile,
  676 + child: Text('Remote Example File'),
  677 + ),
  678 + DropdownMenuItem<Media>(
  679 + value: Media.stream,
  680 + child: Text('Dart Stream'),
  681 + ),
  682 + ],
  683 + ),
  684 + ],
  685 + );
  686 +
  687 + final codecDropdown = Row(
  688 + mainAxisAlignment: MainAxisAlignment.start,
  689 + crossAxisAlignment: CrossAxisAlignment.center,
  690 + children: <Widget>[
  691 + const Padding(
  692 + padding: EdgeInsets.only(right: 16.0),
  693 + child: Text('Codec:'),
  694 + ),
  695 + DropdownButton<Codec>(
  696 + value: _codec,
  697 + onChanged: (newCodec) {
  698 + setCodec(newCodec!);
  699 + _codec = newCodec;
  700 + setState(() {});
  701 + },
  702 + items: const <DropdownMenuItem<Codec>>[
  703 + DropdownMenuItem<Codec>(
  704 + value: Codec.aacADTS,
  705 + child: Text('AAC/ADTS'),
  706 + ),
  707 + DropdownMenuItem<Codec>(
  708 + value: Codec.opusOGG,
  709 + child: Text('Opus/OGG'),
  710 + ),
  711 + DropdownMenuItem<Codec>(
  712 + value: Codec.opusCAF,
  713 + child: Text('Opus/CAF'),
  714 + ),
  715 + DropdownMenuItem<Codec>(
  716 + value: Codec.mp3,
  717 + child: Text('MP3'),
  718 + ),
  719 + DropdownMenuItem<Codec>(
  720 + value: Codec.vorbisOGG,
  721 + child: Text('Vorbis/OGG'),
  722 + ),
  723 + DropdownMenuItem<Codec>(
  724 + value: Codec.pcm16,
  725 + child: Text('PCM16'),
  726 + ),
  727 + DropdownMenuItem<Codec>(
  728 + value: Codec.pcm16WAV,
  729 + child: Text('PCM16/WAV'),
  730 + ),
  731 + DropdownMenuItem<Codec>(
  732 + value: Codec.pcm16AIFF,
  733 + child: Text('PCM16/AIFF'),
  734 + ),
  735 + DropdownMenuItem<Codec>(
  736 + value: Codec.pcm16CAF,
  737 + child: Text('PCM16/CAF'),
  738 + ),
  739 + DropdownMenuItem<Codec>(
  740 + value: Codec.flac,
  741 + child: Text('FLAC'),
  742 + ),
  743 + DropdownMenuItem<Codec>(
  744 + value: Codec.aacMP4,
  745 + child: Text('AAC/MP4'),
  746 + ),
  747 + DropdownMenuItem<Codec>(
  748 + value: Codec.amrNB,
  749 + child: Text('AMR-NB'),
  750 + ),
  751 + DropdownMenuItem<Codec>(
  752 + value: Codec.amrWB,
  753 + child: Text('AMR-WB '),
  754 + ),
  755 + DropdownMenuItem<Codec>(
  756 + value: Codec.pcm8,
  757 + child: Text('PCM8 '),
  758 + ),
  759 + DropdownMenuItem<Codec>(
  760 + value: Codec.pcmFloat32,
  761 + child: Text('PCM Float32 '),
  762 + ),
  763 + DropdownMenuItem<Codec>(
  764 + value: Codec.pcmWebM,
  765 + child: Text('PCM/WebM '),
  766 + ),
  767 + DropdownMenuItem<Codec>(
  768 + value: Codec.opusWebM,
  769 + child: Text('Opus/WebM '),
  770 + ),
  771 + DropdownMenuItem<Codec>(
  772 + value: Codec.vorbisWebM,
  773 + child: Text('Vorbis/WebM '),
  774 + ),
  775 + DropdownMenuItem<Codec>(
  776 + value: Codec.pcmFloat32WAV,
  777 + child: Text('PCM Float32/WAV'),
  778 + ),
  779 + ],
  780 + ),
  781 + ],
  782 + );
  783 +
  784 + return Padding(
  785 + padding: const EdgeInsets.all(8.0),
  786 + child: Column(
  787 + mainAxisAlignment: MainAxisAlignment.start,
  788 + crossAxisAlignment: CrossAxisAlignment.center,
  789 + children: <Widget>[
  790 + Padding(
  791 + padding: const EdgeInsets.only(bottom: 16.0),
  792 + child: mediaDropdown,
  793 + ),
  794 + codecDropdown,
  795 + ],
  796 + ),
  797 + );
  798 + }
  799 +
  800 + void Function()? onPauseResumePlayerPressed() {
  801 + if (playerModule.isPaused || playerModule.isPlaying) {
  802 + return pauseResumePlayer;
  803 + }
  804 + return null;
  805 + }
  806 +
  807 + void Function()? onPauseResumeRecorderPressed() {
  808 + if (recorderModule.isPaused || recorderModule.isRecording) {
  809 + return pauseResumeRecorder;
  810 + }
  811 + return null;
  812 + }
  813 +
  814 + void Function()? onStopPlayerPressed() {
  815 + return (playerModule.isPlaying || playerModule.isPaused)
  816 + ? stopPlayer
  817 + : null;
  818 + }
  819 +
  820 + void Function()? onStartPlayerPressed() {
  821 + if (_media == Media.buffer && kIsWeb) {
  822 + return null;
  823 + }
  824 + if (_media == Media.file ||
  825 + _media == Media.stream ||
  826 + _media == Media.buffer) // A file must be already recorded to play it
  827 + {
  828 + if (_path[_codec.index] == null) return null;
  829 + }
  830 +
  831 + if (_media == Media.stream && _codec != Codec.pcm16) {
  832 + return null;
  833 + }
  834 +
  835 + // Disable the button if the selected codec is not supported
  836 + if (!(_decoderSupported ||
  837 + _codec == Codec.pcm16 ||
  838 + _codec == Codec.pcmFloat32)) {
  839 + return null;
  840 + }
  841 +
  842 + return (playerModule.isStopped) ? startPlayer : null;
  843 + }
  844 +
  845 + void startStopRecorder() {
  846 + if (recorderModule.isRecording || recorderModule.isPaused) {
  847 + stopRecorder();
  848 + } else {
  849 + startRecorder();
  850 + }
  851 + }
  852 +
  853 + void Function()? onStartRecorderPressed() {
  854 + // Disable the button if the selected codec is not supported
  855 + if (!_encoderSupported!) return null;
  856 + if (_media == Media.stream && _codec != Codec.pcm16) return null;
  857 + return startStopRecorder;
  858 + }
  859 +
  860 + AssetImage recorderAssetImage() {
  861 + if (onStartRecorderPressed() == null) {
  862 + return const AssetImage('res/icons/ic_mic_disabled.png');
  863 + }
  864 + return (recorderModule.isStopped)
  865 + ? const AssetImage('res/icons/ic_mic.png')
  866 + : const AssetImage('res/icons/ic_stop.png');
  867 + }
  868 +
  869 + Future<void> setCodec(Codec codec) async {
  870 + _encoderSupported = await recorderModule.isEncoderSupported(codec);
  871 + _decoderSupported = await playerModule.isDecoderSupported(codec);
  872 +
  873 + setState(() {
  874 + _codec = codec;
  875 + });
  876 + }
  877 +
  878 + @override
  879 + Widget build(BuildContext context) {
  880 + final dropdowns = makeDropdowns(context);
  881 +
  882 + Widget recorderSection = Column(
  883 + crossAxisAlignment: CrossAxisAlignment.center,
  884 + mainAxisAlignment: MainAxisAlignment.center,
  885 + children: <Widget>[
  886 + Container(
  887 + margin: const EdgeInsets.only(top: 12.0, bottom: 16.0),
  888 + child: Text(
  889 + _recorderTxt,
  890 + style: const TextStyle(
  891 + fontSize: 35.0,
  892 + color: Colors.black,
  893 + ),
  894 + ),
  895 + ),
  896 + _isRecording
  897 + ? LinearProgressIndicator(
  898 + value: 100.0 / 160.0 * (_dbLevel ?? 1) / 100,
  899 + valueColor:
  900 + const AlwaysStoppedAnimation<Color>(Colors.indigo),
  901 + backgroundColor: Colors.limeAccent)
  902 + : Container(),
  903 + Row(
  904 + mainAxisAlignment: MainAxisAlignment.center,
  905 + crossAxisAlignment: CrossAxisAlignment.center,
  906 + children: <Widget>[
  907 + SizedBox(
  908 + width: 56.0,
  909 + height: 50.0,
  910 + child: ClipOval(
  911 + child: TextButton(
  912 + onPressed: onStartRecorderPressed(),
  913 + //padding: EdgeInsets.all(8.0),
  914 + child: Image(
  915 + image: recorderAssetImage(),
  916 + ),
  917 + ),
  918 + ),
  919 + ),
  920 + SizedBox(
  921 + width: 56.0,
  922 + height: 50.0,
  923 + child: ClipOval(
  924 + child: TextButton(
  925 + onPressed: onPauseResumeRecorderPressed(),
  926 + //disabledColor: Colors.white,
  927 + //padding: EdgeInsets.all(8.0),
  928 + child: Image(
  929 + width: 36.0,
  930 + height: 36.0,
  931 + image: AssetImage(onPauseResumeRecorderPressed() != null
  932 + ? 'res/icons/ic_pause.png'
  933 + : 'res/icons/ic_pause_disabled.png'),
  934 + ),
  935 + ),
  936 + ),
  937 + ),
  938 + ],
  939 + ),
  940 + ]);
  941 +
  942 + Widget playerSection = Column(
  943 + crossAxisAlignment: CrossAxisAlignment.center,
  944 + mainAxisAlignment: MainAxisAlignment.center,
  945 + children: <Widget>[
  946 + Container(
  947 + margin: const EdgeInsets.only(top: 12.0, bottom: 16.0),
  948 + child: Text(
  949 + _playerTxt,
  950 + style: const TextStyle(
  951 + fontSize: 35.0,
  952 + color: Colors.black,
  953 + ),
  954 + ),
  955 + ),
  956 + Row(
  957 + mainAxisAlignment: MainAxisAlignment.center,
  958 + crossAxisAlignment: CrossAxisAlignment.center,
  959 + children: <Widget>[
  960 + SizedBox(
  961 + width: 56.0,
  962 + height: 50.0,
  963 + child: ClipOval(
  964 + child: TextButton(
  965 + onPressed: onStartPlayerPressed(),
  966 + //disabledColor: Colors.white,
  967 + //padding: EdgeInsets.all(8.0),
  968 + child: Image(
  969 + image: AssetImage(onStartPlayerPressed() != null
  970 + ? 'res/icons/ic_play.png'
  971 + : 'res/icons/ic_play_disabled.png'),
  972 + ),
  973 + ),
  974 + ),
  975 + ),
  976 + SizedBox(
  977 + width: 56.0,
  978 + height: 50.0,
  979 + child: ClipOval(
  980 + child: TextButton(
  981 + onPressed: onPauseResumePlayerPressed(),
  982 + //disabledColor: Colors.white,
  983 + //padding: EdgeInsets.all(8.0),
  984 + child: Image(
  985 + width: 36.0,
  986 + height: 36.0,
  987 + image: AssetImage(onPauseResumePlayerPressed() != null
  988 + ? 'res/icons/ic_pause.png'
  989 + : 'res/icons/ic_pause_disabled.png'),
  990 + ),
  991 + ),
  992 + ),
  993 + ),
  994 + SizedBox(
  995 + width: 56.0,
  996 + height: 50.0,
  997 + child: ClipOval(
  998 + child: TextButton(
  999 + onPressed: onStopPlayerPressed(),
  1000 + //disabledColor: Colors.white,
  1001 + //padding: EdgeInsets.all(8.0),
  1002 + child: Image(
  1003 + width: 28.0,
  1004 + height: 28.0,
  1005 + image: AssetImage(onStopPlayerPressed() != null
  1006 + ? 'res/icons/ic_stop.png'
  1007 + : 'res/icons/ic_stop_disabled.png'),
  1008 + ),
  1009 + ),
  1010 + ),
  1011 + ),
  1012 + ],
  1013 + ),
  1014 + SizedBox(
  1015 + height: 30.0,
  1016 + child: Slider(
  1017 + value: min(sliderCurrentPosition, maxDuration),
  1018 + min: 0.0,
  1019 + max: maxDuration,
  1020 + onChanged: (value) async {
  1021 + await seekToPlayer(value.toInt());
  1022 + },
  1023 + divisions: maxDuration == 0.0 ? 1 : maxDuration.toInt())),
  1024 + ],
  1025 + );
  1026 +
  1027 + return Scaffold(
  1028 + appBar: AppBar(
  1029 + title: const Text('Flutter Sound Demo'),
  1030 + ),
  1031 + body: ListView(
  1032 + children: <Widget>[
  1033 + recorderSection,
  1034 + playerSection,
  1035 + dropdowns,
  1036 + ],
  1037 + ),
  1038 + );
  1039 + }
  1040 +}