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 @@
"flutterMode": "release"
},
{
"name": "flutter_tts_ohos",
"cwd": "library/flutter_tts_ohos",
"request": "launch",
"type": "dart"
},
{
"name": "flutter_tts_ohos (profile mode)",
"cwd": "library/flutter_tts_ohos",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "flutter_tts_ohos (release mode)",
"cwd": "library/flutter_tts_ohos",
"request": "launch",
"type": "dart",
"flutterMode": "release"
},
{
"name": "fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new",
"cwd": "library/fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new",
"request": "launch",
... ... @@ -323,6 +343,26 @@
"flutterMode": "release"
},
{
"name": "speech_to_text_wdn_ohos",
"cwd": "library/speech_to_text_wdn_ohos",
"request": "launch",
"type": "dart"
},
{
"name": "speech_to_text_wdn_ohos (profile mode)",
"cwd": "library/speech_to_text_wdn_ohos",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "speech_to_text_wdn_ohos (release mode)",
"cwd": "library/speech_to_text_wdn_ohos",
"request": "launch",
"type": "dart",
"flutterMode": "release"
},
{
"name": "table_calendar-2.3.3",
"cwd": "library/table_calendar-2.3.3",
"request": "launch",
... ... @@ -524,6 +564,26 @@
},
{
"name": "example",
"cwd": "library/flutter_tts_ohos/example",
"request": "launch",
"type": "dart"
},
{
"name": "example (profile mode)",
"cwd": "library/flutter_tts_ohos/example",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "example (release mode)",
"cwd": "library/flutter_tts_ohos/example",
"request": "launch",
"type": "dart",
"flutterMode": "release"
},
{
"name": "example",
"cwd": "library/fluttertpc_flutter_barcode_scanner-af5d0e6d2bc53977f979c4f2b852f46274dc8405_new/example",
"request": "launch",
"type": "dart"
... ... @@ -644,6 +704,26 @@
},
{
"name": "example",
"cwd": "library/speech_to_text_wdn_ohos/example",
"request": "launch",
"type": "dart"
},
{
"name": "example (profile mode)",
"cwd": "library/speech_to_text_wdn_ohos/example",
"request": "launch",
"type": "dart",
"flutterMode": "profile"
},
{
"name": "example (release mode)",
"cwd": "library/speech_to_text_wdn_ohos/example",
"request": "launch",
"type": "dart",
"flutterMode": "release"
},
{
"name": "example",
"cwd": "library/table_calendar-3.1.3/example",
"request": "launch",
"type": "dart"
... ...
... ... @@ -8,8 +8,14 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<!-- 【必须】 移动推送 TPNS SDK 所需权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
... ... @@ -36,6 +42,13 @@
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
</intent>
</queries>
<application
... ...
... ... @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1536M
# android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
android.suppressUnsupportedCompileSdk = 34
android.suppressUnsupportedCompileSdk=34,35
org.gradle.warning.mode=all
# android.jetifier.blacklist=bcprov-jdk15on
... ...
import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart';
// import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart';
class ConstConfig {
static const AMapApiKey amapApiKeys = AMapApiKey(
androidKey: '900f72eeee0f21e435cebb0ef155582a', //测试key
iosKey: '4dfdec97b7bf0b8c13e94777103015a9', //测试key
ohosKey: '7c2081e92ec65bfffa2df0a5464f0c7b'); //我的账户下面的ceshikey
static const AMapPrivacyStatement amapPrivacyStatement =
AMapPrivacyStatement(hasContains: true, hasShow: true, hasAgree: true);
}
// class ConstConfig {
// static const AMapApiKey amapApiKeys = AMapApiKey(
// androidKey: '900f72eeee0f21e435cebb0ef155582a', //测试key
// iosKey: '4dfdec97b7bf0b8c13e94777103015a9', //测试key
// ohosKey: '7c2081e92ec65bfffa2df0a5464f0c7b'); //我的账户下面的ceshikey
// static const AMapPrivacyStatement amapPrivacyStatement =
// AMapPrivacyStatement(hasContains: true, hasShow: true, hasAgree: true);
// }
... ...
// import 'dart:async';
// import 'package:amap_map_fluttify/amap_map_fluttify.dart';
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// import 'package:flutter_easyrefresh/easy_refresh.dart';
// import 'package:one_key/res/colors.dart';
// import 'package:one_key/utils/misc.dart';
// import 'package:one_key/utils/screen_util.dart';
// import 'package:one_key/utils/utils.dart';
// import 'package:one_key/widgets/system_app_bar.dart';
// import 'package:permission_handler/permission_handler.dart';
// import '../../utils/common_utils.dart';
// // import 'package:demo/resources/custom_text_style.dart';
// // import 'package:demo/utils/misc.dart';
// // import 'package:demo/widgets/network_state/page_loading.dart';
// class MapChoicePointPage extends StatefulWidget {
// final String? long;
// final String? lat;
// MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);
// @override
// _MapChoicePointPageState createState() => _MapChoicePointPageState();
// }
// class _MapChoicePointPageState extends State<MapChoicePointPage> {
// AmapController? _controller;
// List<Poi>? poiList;
// static List<PoiModel?> list = [];
// static List<PoiModel> searchlist = [];
// PoiModel? poiModel;
// String keyword = "";
// String? address = "";
// bool isloading = true;
// double latitude = 39.684670899;
// double longitude = 118.17630045;
// double latitudeLocation = 39.684670899;
// double longitudeLocation = 118.17630045;
// List<InputTip> inputTipDatas = [];
// int page = 1;
// EasyRefreshController refreshController = EasyRefreshController();
// bool flag = true;
// @override
// void initState() {
// super.initState();
// if (widget.long != null && widget.long != '' && widget.long != 'null') {
// longitude = double.parse(widget.long!);
// }
// if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {
// latitude = double.parse(widget.lat!);
// }
// WidgetsBinding.instance.addPostFrameCallback((_) async {
// _requestLocationPermission();
// // ama
// // let marker = new AMap.Marker({//添加标记点
// // position: this.position,
// // map: map
// });
// }
// // Future<bool> checkLocationPermission() async {
// // PermissionStatus permissionStatus = await Permission.location.status;
// // if (permissionStatus == PermissionStatus.granted) {
// // return true;
// // } else {
// // return false;
// // }
// // }
// /// 检查权限并定
// // _getLocationPermission() async {
// // if (!(await checkPermission(Permission.location))) {
// // //没有定位权限
// // //申请定位权限
// // _requestLocationPermission();
// // } else {
// // //去定位
// // _requestLocationPermission();
// // }
// // }
// /// 获取定位权限
// _requestLocationPermission() async {
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// bool canLocation = false;
// if (!(await checkPermission(Permission.location))) {
// //没有定位权限
// //申请定位权限
// canLocation = await requestPermission(Permission.location);
// } else {
// canLocation = true;
// }
// // bool canLocation = await requestPermission(Permission.location);
// // 单次定位
// if (canLocation) {
// Future.delayed(Duration(milliseconds: 200), () async {
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// final location = await AmapLocation.instance.fetchLocation(
// // needAddress: true,
// // mode: LocationAccuracy.High,
// // timeout: Duration(seconds: 10)
// );
// if (location.city == null || location.city == '') //网络不好,定位失败
// {
// // App.sp.setString("lat", "39.684670899");
// // App.sp.setString("lng", "118.17630045");
// } else {
// if (widget.long == null ||
// widget.long == '' ||
// widget.long == 'null') {
// latitude = location.latLng!.latitude;
// longitude = location.latLng!.longitude;
// if (_controller != null) {
// _controller!.setCenterCoordinate(LatLng(
// location.latLng!.latitude, location.latLng!.longitude));
// }
// page = 1;
// _loadData(
// LatLng(location.latLng!.latitude, location.latLng!.longitude));
// setState(() {});
// }
// latitudeLocation = location.latLng!.latitude;
// longitudeLocation = location.latLng!.longitude;
// }
// });
// } else {
// //无权限
// }
// }
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// resizeToAvoidBottomInset: false, //防止底部布局被顶起
// appBar: SystemAppBar(
// '选择位置信息',
// onTap: () {
// if (Navigator.canPop(context)) {
// Navigator.pop(context);
// }
// },
// ),
// body: Column(
// children: <Widget>[
// // Theme(
// // data: new
// // ThemeData(
// // // primaryColor: MyColours.color_438E93,
// // // hintColor: MyColours.color_438E93),
// // child:
// // Container(
// // color: MyColours.color_438E93,
// // decoration: BoxDecoration(
// // color: MyColours.color_438E93,
// // boxShadow: [
// // BoxShadow(color: Colors.white, spreadRadius: 1),
// // ],
// // ),
// // padding: EdgeInsets.all(5),
// // child:
// // ),
// // ),
// // ListView.builder(
// // shrinkWrap: true,
// // itemCount: inputTipDatas.length,
// // itemBuilder: (context, index) {
// // InputTip inputTip = inputTipDatas[index];
// // return InkWell(
// // onTap: () {
// // // searchAroundAddress(inputTip.name ?? '');
// // // searchPoiId(inputTip.poiId ?? '');
// // // _loadData(inputTip.coordinate ??
// // // LatLng(latitude, longitude));
// // },
// // child: Container(
// // child: Row(
// // children: [
// // Text(
// // inputTip.name ?? '',
// // style: TextStyle(
// // fontSize: font(15),
// // color: MyColours.color_515151),
// // ),
// // HEmptyView(10),
// // Expanded(
// // child: Text(
// // (inputTip.district ?? '') +
// // (inputTip.address ?? ''),
// // style: TextStyle(
// // fontSize: font(13),
// // color: MyColours.color_999999),
// // ),
// // ),
// // ],
// // )));
// // })
// // ],
// // ),
// Stack(
// children: [
// Container(
// height: w(300),
// child: Stack(
// children: <Widget>[
// AmapView(
// showZoomControl: false,
// /// 是否显示指南针控件
// showCompass: true,
// /// 是否显示比例尺控件
// showScaleControl: true,
// /// 是否使能缩放手势
// zoomGesturesEnabled: true,
// /// 是否使能滚动手势
// scrollGesturesEnabled: true,
// /// 是否使能旋转手势
// rotateGestureEnabled: false,
// centerCoordinate: LatLng(latitude, longitude),
// maskDelay: Duration(milliseconds: 500),
// zoomLevel: 19,
// onMapCreated: (controller) async {
// _controller = controller;
// _controller!
// .setCenterCoordinate(LatLng(latitude, longitude));
// // if (await requestPermission(PermissionGroup.location)) {
// // await controller.showMyLocation(true);
// // await controller?.showLocateControl(true);
// // final latLng = await _controller?.getLocation(
// // delay: Duration(seconds: 2));
// // await enableFluttifyLog(false); // 关闭log
// // _loadData(latLng);
// // } else {
// // //无权限
// // _showLocPemWidget();
// // }
// },
// // markers: [],
// onMapMoveEnd: (MapMove move) async {
// latitude = move.coordinate!.latitude;
// longitude = move.coordinate!.longitude;
// page = 1;
// _loadData(move.coordinate!);
// },
// ),
// Center(
// child: Icon(
// Icons.place,
// size: w(32),
// color: Color(0xFFFF0000),
// ),
// ),
// Positioned(
// right: w(10),
// bottom: w(10),
// child: InkWell(
// onTap: () {
// _controller!.setCenterCoordinate(
// LatLng(latitudeLocation, longitudeLocation));
// },
// child: Container(
// decoration: BoxDecoration(
// color: MyColours.color_ffffff,
// borderRadius: BorderRadius.circular(r(5))),
// padding: EdgeInsets.all(w(5)),
// child: Image.asset(
// Utils.getImgPath('location_map'),
// width: w(25),
// ),
// )),
// )
// ],
// ),
// ),
// Positioned(
// top: w(10),
// left: w(20),
// right: w(20),
// child: Container(
// // height: w(45),
// padding: EdgeInsets.symmetric(vertical: w(10)),
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(r(10))),
// child: TextField(
// textAlignVertical: TextAlignVertical.center,
// style: TextStyle(
// color: MyColours.color_515151,
// fontSize: font(15),
// ),
// controller:
// TextEditingController.fromValue(TextEditingValue(
// // 设置内容
// text: keyword,
// selection: TextSelection.fromPosition(TextPosition(
// affinity: TextAffinity.downstream,
// offset: keyword.length)),
// // 保持光标在最后
// )),
// decoration: InputDecoration(
// // border: b,
// // border: OutlineInputBorder(
// // borderRadius: BorderRadius.all(Radius.circular(40)),
// // ),
// border: OutlineInputBorder(borderSide: BorderSide.none),
// hintText: '输入关键字',
// isCollapsed: true,
// hintStyle: TextStyle(
// color: MyColours.color_999999, fontSize: font(15)),
// // contentPadding: const EdgeInsets.symmetric(
// // vertical: 8, horizontal: 1),
// prefixIconConstraints: BoxConstraints(maxWidth: w(40)),
// prefixIcon: Padding(
// padding: EdgeInsets.only(left: w(10), right: w(10)),
// child: SizedBox(
// width: w(30),
// child: Image.asset(
// Utils.getImgPath('search_black'),
// ))),
// suffixIconConstraints: BoxConstraints(maxWidth: w(32)),
// suffixIcon: InkWell(
// child: Padding(
// padding: EdgeInsets.only(left: w(10), right: w(10)),
// child: SizedBox(
// width: w(22),
// child: Image.asset(
// Utils.getImgPath('delete_black'),
// ))),
// onTap: () {
// keyword = "";
// setState(() {});
// },
// ),
// fillColor: Colors.white,
// filled: true,
// ),
// inputFormatters: [],
// //内容改变的回调
// onChanged: (text) {
// print('change $text');
// keyword = text;
// //搜索
// JhCommonUtils.debounce(
// () => _fetchInputTips(text.toString()));
// },
// //内容提交(按回车)的回调
// onSubmitted: (text) {
// print('submit $text');
// // 触发关闭弹出来的键盘。
// keyword = text;
// FocusScope.of(context).requestFocus(FocusNode());
// setState(() {
// // isloading = true;
// });
// // _fetchInputTips(text.toString());
// // searchAroundAddress(text.toString());
// },
// //按回车时调用
// onEditingComplete: () {
// print('onEditingComplete');
// },
// ),
// ),
// )
// ],
// ),
// Expanded(
// flex: 1,
// child: Visibility(
// visible: !isloading,
// maintainSize: false,
// maintainSemantics: false,
// maintainInteractivity: false,
// replacement: Center(
// child: CupertinoActivityIndicator(),
// ),
// child: EasyRefresh.custom(
// controller: refreshController,
// slivers: [
// SliverList(
// delegate: SliverChildBuilderDelegate(
// (BuildContext context, int position) {
// print("itemBuilder" + list.length.toString());
// PoiModel item = list[position]!;
// return InkWell(
// child: Column(
// children: <Widget>[
// Container(
// margin: EdgeInsets.only(
// top: 8, bottom: 5, left: 10),
// child: Row(
// children: <Widget>[
// Icon(
// Icons.place,
// size: 20.0,
// color: position == 0
// ? Colors.green
// : Colors.grey,
// ),
// Expanded(
// child: Text(item.title,
// style: TextStyle(
// fontSize: 16,
// color: position == 0
// ? Colors.green
// : Color(0xFF787878))))
// ],
// ),
// ),
// Container(
// margin: EdgeInsets.only(
// top: 5, bottom: 5, left: 18),
// alignment: Alignment.centerLeft,
// child: Text(
// item.address!,
// style: TextStyle(
// fontSize: 14,
// color: Color(0xFF646464),
// ),
// ),
// ),
// Divider(
// height: 1,
// )
// ],
// ),
// onTap: () async {
// // await _controller.setCenterCoordinate(
// // LatLng(item.latLng.latitude, item.latLng.longitude),
// // zoomLevel: 16);
// if (Navigator.canPop(context)) {
// Navigator.pop(context, {
// 'address': item.address,
// 'lat': item.latLng!.latitude.toString(),
// 'lng': item.latLng!.longitude.toString()
// });
// }
// },
// );
// },
// childCount: list.length,
// ),
// )
// ],
// onRefresh: () async {
// if (flag) {
// page = 1;
// _loadData(LatLng(latitude, longitude));
// }
// },
// onLoad: () async {
// if (flag) {
// page++;
// _loadData(LatLng(latitude, longitude),
// showloading: false);
// }
// },
// )),
// ),
// ],
// ),
// );
// }
// _fetchInputTips(String text) async {
// flag = false;
// page = 1;
// // setState(() {
// // isloading = true;
// // });
// /// 逆地理编码(坐标转地址)
// ///
// ///
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// LatLng latLng = LatLng(latitude, longitude);
// ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(latLng);
// // print(await reGeocodeList.toFutureString());
// address = reGeocodeList.formatAddress;
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// inputTipDatas = await AmapSearch.instance.fetchInputTips(
// text,
// city: "",
// );
// print(inputTipDatas);
// poiModel = new PoiModel("当前位置", address, latLng);
// list.clear();
// list.add(poiModel);
// for (var inputTip in inputTipDatas) {
// String? title = await inputTip.name ?? '';
// String? cityStr =
// await (inputTip.district ?? '') + (inputTip.address ?? '');
// LatLng? latLng = await inputTip.coordinate;
// list.add(new PoiModel(title.toString(), cityStr, latLng));
// }
// print(list);
// setState(() {
// // isloading = false;
// });
// }
// void _loadData(LatLng latLng, {showloading = true}) async {
// flag = true;
// setState(() {
// if (showloading) {
// isloading = true;
// }
// });
// /// 逆地理编码(坐标转地址)
// ///
// ///
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// if (page == 1) {
// ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(
// latLng,
// );
// // print(await reGeocodeList.toFutureString());
// address = reGeocodeList.formatAddress;
// poiModel = new PoiModel("当前位置", address, latLng);
// list.clear();
// list.add(poiModel);
// }
// final poiList =
// await AmapSearch.instance.searchAround(latLng, city: "", page: page);
// for (var poi in poiList) {
// String? title = await poi.title;
// String? cityName = await poi.cityName;
// String? provinceName = await poi.provinceName;
// String? address = await poi.address;
// LatLng? latLng = await poi.latLng;
// String? bussniss = poi.businessArea;
// list.add(new PoiModel(
// title.toString(),
// provinceName.toString() +
// cityName.toString() +
// address.toString() +
// bussniss.toString(),
// latLng));
// }
// setState(() {
// if (showloading) {
// isloading = false;
// }
// });
// }
// // void searchPoiId(String text) async {
// // await AmapLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// // Poi? poi = await AmapSearch.instance.searchPoiId(
// // text,
// // );
// // print(poi);
// // }
// // void searchAroundAddress(String text) async {
// // await AmapLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// // final poiList = await AmapSearch.instance.searchKeyword(
// // text,
// // city: "",
// // );
// // // final poiList = await AmapSearch.instance.searchAround(
// // // LatLng(latitude, longitude),
// // // city: "",
// // // radius: 100000000000000
// // // );
// // list.clear();
// // list.add(poiModel);
// // for (var poi in poiList) {
// // String? title = await poi.title;
// // LatLng? latLng = await poi.latLng;
// // String? cityName = await poi.cityName;
// // String? provinceName = await poi.provinceName;
// // String? address = await poi.address;
// // list.add(new PoiModel(
// // title.toString(),
// // provinceName.toString() + cityName.toString() + address.toString(),
// // latLng));
// // }
// // setState(() {
// // isloading = false;
// // FocusScope.of(context).requestFocus(FocusNode());
// // });
// // }
// }
// class PoiModel {
// LatLng? latLng;
// String title;
// String? address;
// PoiModel(this.title, this.address, this.latLng);
// }
import 'dart:async';
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/misc.dart';
import 'package:one_key/utils/screen_util.dart';
import 'package:one_key/utils/utils.dart';
import 'package:one_key/widgets/system_app_bar.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../utils/common_utils.dart';
// import 'package:demo/resources/custom_text_style.dart';
// import 'package:demo/utils/misc.dart';
// import 'package:demo/widgets/network_state/page_loading.dart';
class MapChoicePointPage extends StatefulWidget {
final String? long;
final String? lat;
MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);
@override
_MapChoicePointPageState createState() => _MapChoicePointPageState();
}
class _MapChoicePointPageState extends State<MapChoicePointPage> {
AmapController? _controller;
List<Poi>? poiList;
static List<PoiModel?> list = [];
static List<PoiModel> searchlist = [];
PoiModel? poiModel;
String keyword = "";
String? address = "";
bool isloading = true;
double latitude = 39.684670899;
double longitude = 118.17630045;
double latitudeLocation = 39.684670899;
double longitudeLocation = 118.17630045;
List<InputTip> inputTipDatas = [];
int page = 1;
EasyRefreshController refreshController = EasyRefreshController();
bool flag = true;
@override
void initState() {
super.initState();
if (widget.long != null && widget.long != '' && widget.long != 'null') {
longitude = double.parse(widget.long!);
}
if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {
latitude = double.parse(widget.lat!);
}
WidgetsBinding.instance.addPostFrameCallback((_) async {
_requestLocationPermission();
// ama
// let marker = new AMap.Marker({//添加标记点
// position: this.position,
// map: map
});
}
// Future<bool> checkLocationPermission() async {
// PermissionStatus permissionStatus = await Permission.location.status;
// if (permissionStatus == PermissionStatus.granted) {
// return true;
// } else {
// return false;
// }
// }
/// 检查权限并定
// _getLocationPermission() async {
// if (!(await checkPermission(Permission.location))) {
// //没有定位权限
// //申请定位权限
// _requestLocationPermission();
// } else {
// //去定位
// _requestLocationPermission();
// }
// }
/// 获取定位权限
_requestLocationPermission() async {
await AmapLocation.instance.updatePrivacyShow(true);
await AmapLocation.instance.updatePrivacyAgree(true);
bool canLocation = false;
if (!(await checkPermission(Permission.location))) {
//没有定位权限
//申请定位权限
canLocation = await requestPermission(Permission.location);
} else {
canLocation = true;
}
// bool canLocation = await requestPermission(Permission.location);
// 单次定位
if (canLocation) {
Future.delayed(Duration(milliseconds: 200), () async {
await AmapLocation.instance.updatePrivacyShow(true);
await AmapLocation.instance.updatePrivacyAgree(true);
final location = await AmapLocation.instance.fetchLocation(
// needAddress: true,
// mode: LocationAccuracy.High,
// timeout: Duration(seconds: 10)
);
if (location.city == null || location.city == '') //网络不好,定位失败
{
// App.sp.setString("lat", "39.684670899");
// App.sp.setString("lng", "118.17630045");
} else {
if (widget.long == null ||
widget.long == '' ||
widget.long == 'null') {
latitude = location.latLng!.latitude;
longitude = location.latLng!.longitude;
if (_controller != null) {
_controller!.setCenterCoordinate(LatLng(
location.latLng!.latitude, location.latLng!.longitude));
}
page = 1;
_loadData(
LatLng(location.latLng!.latitude, location.latLng!.longitude));
setState(() {});
}
latitudeLocation = location.latLng!.latitude;
longitudeLocation = location.latLng!.longitude;
}
});
} else {
//无权限
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false, //防止底部布局被顶起
appBar: SystemAppBar(
'选择位置信息',
onTap: () {
if (Navigator.canPop(context)) {
Navigator.pop(context);
}
},
),
body: Column(
children: <Widget>[
// Theme(
// data: new
// ThemeData(
// // primaryColor: MyColours.color_438E93,
// // hintColor: MyColours.color_438E93),
// child:
// Container(
// color: MyColours.color_438E93,
// decoration: BoxDecoration(
// color: MyColours.color_438E93,
// boxShadow: [
// BoxShadow(color: Colors.white, spreadRadius: 1),
// ],
// ),
// padding: EdgeInsets.all(5),
// child:
// ),
// ),
// ListView.builder(
// shrinkWrap: true,
// itemCount: inputTipDatas.length,
// itemBuilder: (context, index) {
// InputTip inputTip = inputTipDatas[index];
// return InkWell(
// onTap: () {
// // searchAroundAddress(inputTip.name ?? '');
// // searchPoiId(inputTip.poiId ?? '');
// // _loadData(inputTip.coordinate ??
// // LatLng(latitude, longitude));
// },
// child: Container(
// child: Row(
// children: [
// Text(
// inputTip.name ?? '',
// style: TextStyle(
// fontSize: font(15),
// color: MyColours.color_515151),
// ),
// HEmptyView(10),
// Expanded(
// child: Text(
// (inputTip.district ?? '') +
// (inputTip.address ?? ''),
// style: TextStyle(
// fontSize: font(13),
// color: MyColours.color_999999),
// ),
// ),
// ],
// )));
// })
// ],
// ),
Stack(
children: [
Container(
height: w(300),
child: Stack(
children: <Widget>[
AmapView(
showZoomControl: false,
/// 是否显示指南针控件
showCompass: true,
/// 是否显示比例尺控件
showScaleControl: true,
/// 是否使能缩放手势
zoomGesturesEnabled: true,
/// 是否使能滚动手势
scrollGesturesEnabled: true,
/// 是否使能旋转手势
rotateGestureEnabled: false,
centerCoordinate: LatLng(latitude, longitude),
maskDelay: Duration(milliseconds: 500),
zoomLevel: 19,
onMapCreated: (controller) async {
_controller = controller;
_controller!
.setCenterCoordinate(LatLng(latitude, longitude));
// if (await requestPermission(PermissionGroup.location)) {
// await controller.showMyLocation(true);
// await controller?.showLocateControl(true);
// final latLng = await _controller?.getLocation(
// delay: Duration(seconds: 2));
// await enableFluttifyLog(false); // 关闭log
// _loadData(latLng);
// } else {
// //无权限
// _showLocPemWidget();
// }
},
// markers: [],
onMapMoveEnd: (MapMove move) async {
latitude = move.coordinate!.latitude;
longitude = move.coordinate!.longitude;
page = 1;
_loadData(move.coordinate!);
},
),
Center(
child: Icon(
Icons.place,
size: w(32),
color: Color(0xFFFF0000),
),
),
Positioned(
right: w(10),
bottom: w(10),
child: InkWell(
onTap: () {
_controller!.setCenterCoordinate(
LatLng(latitudeLocation, longitudeLocation));
},
child: Container(
decoration: BoxDecoration(
color: MyColours.color_ffffff,
borderRadius: BorderRadius.circular(r(5))),
padding: EdgeInsets.all(w(5)),
child: Image.asset(
Utils.getImgPath('location_map'),
width: w(25),
),
)),
)
],
),
),
Positioned(
top: w(10),
left: w(20),
right: w(20),
child: Container(
// height: w(45),
padding: EdgeInsets.symmetric(vertical: w(10)),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(r(10))),
child: TextField(
textAlignVertical: TextAlignVertical.center,
style: TextStyle(
color: MyColours.color_515151,
fontSize: font(15),
),
controller:
TextEditingController.fromValue(TextEditingValue(
// 设置内容
text: keyword,
selection: TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream,
offset: keyword.length)),
// 保持光标在最后
)),
decoration: InputDecoration(
// border: b,
// border: OutlineInputBorder(
// borderRadius: BorderRadius.all(Radius.circular(40)),
// ),
border: OutlineInputBorder(borderSide: BorderSide.none),
hintText: '输入关键字',
isCollapsed: true,
hintStyle: TextStyle(
color: MyColours.color_999999, fontSize: font(15)),
// contentPadding: const EdgeInsets.symmetric(
// vertical: 8, horizontal: 1),
prefixIconConstraints: BoxConstraints(maxWidth: w(40)),
prefixIcon: Padding(
padding: EdgeInsets.only(left: w(10), right: w(10)),
child: SizedBox(
width: w(30),
child: Image.asset(
Utils.getImgPath('search_black'),
))),
suffixIconConstraints: BoxConstraints(maxWidth: w(32)),
suffixIcon: InkWell(
child: Padding(
padding: EdgeInsets.only(left: w(10), right: w(10)),
child: SizedBox(
width: w(22),
child: Image.asset(
Utils.getImgPath('delete_black'),
))),
onTap: () {
keyword = "";
setState(() {});
},
),
fillColor: Colors.white,
filled: true,
),
inputFormatters: [],
//内容改变的回调
onChanged: (text) {
print('change $text');
keyword = text;
//搜索
JhCommonUtils.debounce(
() => _fetchInputTips(text.toString()));
},
//内容提交(按回车)的回调
onSubmitted: (text) {
print('submit $text');
// 触发关闭弹出来的键盘。
keyword = text;
FocusScope.of(context).requestFocus(FocusNode());
setState(() {
// isloading = true;
});
// _fetchInputTips(text.toString());
// searchAroundAddress(text.toString());
},
//按回车时调用
onEditingComplete: () {
print('onEditingComplete');
},
),
),
)
],
),
Expanded(
flex: 1,
child: Visibility(
visible: !isloading,
maintainSize: false,
maintainSemantics: false,
maintainInteractivity: false,
replacement: Center(
child: CupertinoActivityIndicator(),
),
child: EasyRefresh.custom(
controller: refreshController,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int position) {
print("itemBuilder" + list.length.toString());
PoiModel item = list[position]!;
return InkWell(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 8, bottom: 5, left: 10),
child: Row(
children: <Widget>[
Icon(
Icons.place,
size: 20.0,
color: position == 0
? Colors.green
: Colors.grey,
),
Expanded(
child: Text(item.title,
style: TextStyle(
fontSize: 16,
color: position == 0
? Colors.green
: Color(0xFF787878))))
],
),
),
Container(
margin: EdgeInsets.only(
top: 5, bottom: 5, left: 18),
alignment: Alignment.centerLeft,
child: Text(
item.address!,
style: TextStyle(
fontSize: 14,
color: Color(0xFF646464),
),
),
),
Divider(
height: 1,
)
],
),
onTap: () async {
// await _controller.setCenterCoordinate(
// LatLng(item.latLng.latitude, item.latLng.longitude),
// zoomLevel: 16);
if (Navigator.canPop(context)) {
Navigator.pop(context, {
'address': item.address,
'lat': item.latLng!.latitude.toString(),
'lng': item.latLng!.longitude.toString()
});
}
},
);
},
childCount: list.length,
),
)
],
onRefresh: () async {
if (flag) {
page = 1;
_loadData(LatLng(latitude, longitude));
}
},
onLoad: () async {
if (flag) {
page++;
_loadData(LatLng(latitude, longitude),
showloading: false);
}
},
)),
),
],
),
);
}
_fetchInputTips(String text) async {
flag = false;
page = 1;
// setState(() {
// isloading = true;
// });
/// 逆地理编码(坐标转地址)
///
///
await AmapLocation.instance.updatePrivacyShow(true);
await AmapLocation.instance.updatePrivacyAgree(true);
LatLng latLng = LatLng(latitude, longitude);
ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(latLng);
// print(await reGeocodeList.toFutureString());
address = reGeocodeList.formatAddress;
await AmapLocation.instance.updatePrivacyShow(true);
await AmapLocation.instance.updatePrivacyAgree(true);
inputTipDatas = await AmapSearch.instance.fetchInputTips(
text,
city: "",
);
print(inputTipDatas);
poiModel = new PoiModel("当前位置", address, latLng);
list.clear();
list.add(poiModel);
for (var inputTip in inputTipDatas) {
String? title = await inputTip.name ?? '';
String? cityStr =
await (inputTip.district ?? '') + (inputTip.address ?? '');
LatLng? latLng = await inputTip.coordinate;
list.add(new PoiModel(title.toString(), cityStr, latLng));
}
print(list);
setState(() {
// isloading = false;
});
}
void _loadData(LatLng latLng, {showloading = true}) async {
flag = true;
setState(() {
if (showloading) {
isloading = true;
}
});
/// 逆地理编码(坐标转地址)
///
///
await AmapLocation.instance.updatePrivacyShow(true);
await AmapLocation.instance.updatePrivacyAgree(true);
if (page == 1) {
ReGeocode reGeocodeList = await AmapSearch.instance.searchReGeocode(
latLng,
);
// print(await reGeocodeList.toFutureString());
address = reGeocodeList.formatAddress;
poiModel = new PoiModel("当前位置", address, latLng);
list.clear();
list.add(poiModel);
}
final poiList =
await AmapSearch.instance.searchAround(latLng, city: "", page: page);
for (var poi in poiList) {
String? title = await poi.title;
String? cityName = await poi.cityName;
String? provinceName = await poi.provinceName;
String? address = await poi.address;
LatLng? latLng = await poi.latLng;
String? bussniss = poi.businessArea;
list.add(new PoiModel(
title.toString(),
provinceName.toString() +
cityName.toString() +
address.toString() +
bussniss.toString(),
latLng));
}
setState(() {
if (showloading) {
isloading = false;
}
});
}
// void searchPoiId(String text) async {
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// Poi? poi = await AmapSearch.instance.searchPoiId(
// text,
// );
// print(poi);
// }
// void searchAroundAddress(String text) async {
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// final poiList = await AmapSearch.instance.searchKeyword(
// text,
// city: "",
// );
// // final poiList = await AmapSearch.instance.searchAround(
// // LatLng(latitude, longitude),
// // city: "",
// // radius: 100000000000000
// // );
// list.clear();
// list.add(poiModel);
// for (var poi in poiList) {
// String? title = await poi.title;
// LatLng? latLng = await poi.latLng;
// String? cityName = await poi.cityName;
// String? provinceName = await poi.provinceName;
// String? address = await poi.address;
// list.add(new PoiModel(
// title.toString(),
// provinceName.toString() + cityName.toString() + address.toString(),
// latLng));
// }
// setState(() {
// isloading = false;
// FocusScope.of(context).requestFocus(FocusNode());
// });
// }
}
class PoiModel {
LatLng? latLng;
String title;
String? address;
PoiModel(this.title, this.address, this.latLng);
}
... ...
import 'dart:async';
// import 'dart:js_interop';
// import 'dart:async';
// // import 'dart:js_interop';
import 'package:flutter/material.dart';
// import 'package:flutter/material.dart';
import 'package:csp_amap_flutter_map/csp_amap_flutter_map.dart';
import 'package:csp_amap_flutter_location/amap_flutter_location.dart';
import 'package:csp_amap_flutter_location/amap_location_option.dart';
import 'package:flutter/cupertino.dart';
// import 'package:csp_amap_flutter_map/csp_amap_flutter_map.dart';
// import 'package:csp_amap_flutter_location/amap_flutter_location.dart';
// import 'package:csp_amap_flutter_location/amap_location_option.dart';
// import 'package:flutter/cupertino.dart';
// import 'package:flutter/material.dart';
// // import 'package:flutter/material.dart';
import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart';
// import 'package:csp_amap_flutter_base/csp_amap_flutter_base.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:one_key/pages/create_store/const_config.dart';
import 'package:one_key/pages/create_store/map_inputs_model.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/common_utils.dart';
import 'package:one_key/utils/misc.dart';
import 'package:one_key/utils/screen_util.dart';
import 'package:one_key/utils/utils.dart';
import 'package:one_key/widgets/system_app_bar.dart';
import 'package:permission_handler/permission_handler.dart';
// import '../../utils/common_utils.dart';
// import 'package:demo/resources/custom_text_style.dart';
// import 'package:demo/utils/misc.dart';
// import 'package:demo/widgets/network_state/page_loading.dart';
class MapChoicePointPage extends StatefulWidget {
final String? long;
final String? lat;
MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);
@override
_MapChoicePointPageState createState() => _MapChoicePointPageState();
}
class _MapChoicePointPageState extends State<MapChoicePointPage> {
late AMapController _mapController;
final double _minZoom = 3;
final double _maxZoom = 20;
String? _currentZoom;
// List<Poi>? poiList;
static List<PoiModel?> list = [];
static List<PoiModel> searchlist = [];
PoiModel? poiModel;
String keyword = "";
String? address = "";
bool isloading = true;
double latitude = 39.684670899;
double longitude = 118.17630045;
double latitudeLocation = 39.684670899;
double longitudeLocation = 118.17630045;
List<MapInputsModel> inputTipDatas = [];
int page = 1;
EasyRefreshController refreshController = EasyRefreshController();
bool flag = true;
/// 存储定位结果
Map<String, Object>? _locationResult;
/// 定位结果监听器
StreamSubscription<Map<String, Object>>? _locationListener;
/// 地理位置解析结果监听器
StreamSubscription<Map<String, Object>>? _geocodeSearchListener;
/// 高德定位插件实例
final AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();
@override
void initState() {
super.initState();
if (widget.long != null && widget.long != '' && widget.long != 'null') {
longitude = double.parse(widget.long!);
}
if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {
latitude = double.parse(widget.lat!);
}
WidgetsBinding.instance.addPostFrameCallback((_) async {
AMapInitializer.init(context, apiKey: ConstConfig.amapApiKeys);
AMapInitializer.updatePrivacyAgree(ConstConfig.amapPrivacyStatement);
AMapFlutterLocation.setApiKey("1dbf56e2e8a4d0e4cdc2df9efd36bc71",
"dfb64c0463cb53927914364b5c09aba0",
ohosKey: "7c2081e92ec65bfffa2df0a5464f0c7b");
/// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作
///
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
/// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
///
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
///
/// [hasContains] 隐私声明中是否包含高德隐私政策说明
///
/// [hasShow] 隐私权政策是否弹窗展示告知用户
AMapFlutterLocation.updatePrivacyShow(true, true);
/// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作
///
/// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
///
/// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
///
/// [hasAgree] 隐私权政策是否已经取得用户同意
AMapFlutterLocation.updatePrivacyAgree(true);
_requestLocationPermission();
// ama
// let marker = new AMap.Marker({//添加标记点
// position: this.position,
// map: map
});
_geocodeSearchListener = _locationPlugin
.onGeocodeSearchChange()
.listen((Map<String, Object> result) {
// setState(() {
if (result.containsKey('errorCode')) {
Utils.showToast(result['errorInfo'].toString());
} else {
_locationResult = result;
print(_locationResult);
}
});
/// 注册定位结果监听
/// 通过监听器接收定位结果并更新UI
_locationListener = _locationPlugin
.onLocationChanged()
.listen((Map<String, Object> result) {
// setState(() {
if (result.containsKey('errorCode')) {
Utils.showToast(result['errorInfo'].toString());
} else {
_locationResult = result;
print(_locationResult);
if (result['latitude'] == null || result['latitude'] == '') //网络不好,定位失败
{
// App.sp.setString("lat", "39.684670899");
// App.sp.setString("lng", "118.17630045");
} else {
if (widget.long == null ||
widget.long == '' ||
widget.long == 'null') {
latitude = double.parse(result['latitude'].toString());
longitude = double.parse(result['longitude'].toString());
// if (_mapController != null) {
_mapController.moveCamera(
CameraUpdate.newLatLng(LatLng(latitude, longitude)));
// }
page = 1;
// _loadData(LatLng(latitude, longitude));
// setState(() {});
}
latitudeLocation = latitude;
longitudeLocation = longitude;
_mapController.moveCamera(
CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),
animated: true,
);
_loadData(LatLng(latitude, longitude));
}
}
});
}
@override
void dispose() {
super.dispose();
/// 移除定位监听
/// 防止内存泄漏
if (null != _locationListener) {
_locationListener?.cancel();
}
if (null != _geocodeSearchListener) {
_geocodeSearchListener?.cancel();
}
/// 销毁定位
/// 释放定位资源
_locationPlugin.destroy();
}
// Future<bool> checkLocationPermission() async {
// PermissionStatus permissionStatus = await Permission.location.status;
// if (permissionStatus == PermissionStatus.granted) {
// return true;
// } else {
// return false;
// }
// }
/// 检查权限并定
// _getLocationPermission() async {
// if (!(await checkPermission(Permission.location))) {
// //没有定位权限
// //申请定位权限
// _requestLocationPermission();
// } else {
// //去定位
// _requestLocationPermission();
// }
// }
/// 设置定位参数
/// 配置定位选项,如精度、频率等
void _setLocationOption() {
AMapLocationOption locationOption = new AMapLocationOption();
/// 是否单次定位
/// false表示连续定位
locationOption.onceLocation = true;
/// 是否需要返回逆地理信息
/// true表示需要返回地址信息
locationOption.needAddress = true;
/// 是否需要返回逆地理编码信息
locationOption.locatingWithReGeocode = true;
/// 逆地理信息的语言类型
/// 默认为自动适配当前系统语言
locationOption.geoLanguage = GeoLanguage.DEFAULT;
/// iOS 14定位精度权限设置
/// 设置为模糊定位精度
locationOption.desiredLocationAccuracyAuthorizationMode =
AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;
/// iOS 14精确定位目的key
/// 需要与info.plist中配置一致
locationOption.fullAccuracyPurposeKey = "AMapLocationScene";
/// 设置Android端连续定位的定位间隔
/// 单位:毫秒
locationOption.locationInterval = 2000;
/// 设置Android端的定位模式
/// 可选值:
/// [AMapLocationMode.Battery_Saving] 低功耗模式
/// [AMapLocationMode.Device_Sensors] 仅设备模式
/// [AMapLocationMode.Hight_Accuracy] 高精度模式
locationOption.locationMode = AMapLocationMode.Hight_Accuracy;
/// 设置iOS端的定位最小更新距离
/// -1表示不限制距离
locationOption.distanceFilter = -1;
/// 设置iOS端期望的定位精度
/// 可选值:
/// [DesiredAccuracy.Best] 最高精度
/// [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度
/// [DesiredAccuracy.NearestTenMeters] 10米
/// [DesiredAccuracy.Kilometer] 1000米
/// [DesiredAccuracy.ThreeKilometers] 3000米
locationOption.desiredAccuracy = DesiredAccuracy.Best;
/// 设置iOS端是否允许系统暂停定位
/// false表示不允许系统暂停定位
locationOption.pausesLocationUpdatesAutomatically = false;
/// 将定位参数设置给定位插件
_locationPlugin.setLocationOption(locationOption);
}
/// 获取定位权限
_requestLocationPermission() async {
/// [hasShow] 隐私权政策是否弹窗展示告知用户
AMapFlutterLocation.updatePrivacyShow(true, true);
/// [hasAgree] 隐私权政策是否已经取得用户同意
AMapFlutterLocation.updatePrivacyAgree(true);
// await AMapFlutterLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
bool canLocation = false;
if (!(await checkPermission(Permission.location))) {
//没有定位权限
//申请定位权限
canLocation = await requestPermission(Permission.location);
} else {
canLocation = true;
}
// bool canLocation = await requestPermission(Permission.location);
// 单次定位
if (canLocation) {
Future.delayed(Duration(milliseconds: 200), () async {
/// [hasShow] 隐私权政策是否弹窗展示告知用户
AMapFlutterLocation.updatePrivacyShow(true, true);
/// [hasAgree] 隐私权政策是否已经取得用户同意
AMapFlutterLocation.updatePrivacyAgree(true);
_startLocation();
// final location = await AmapLocation.instance.fetchLocation(
// // needAddress: true,
// // mode: LocationAccuracy.High,
// // timeout: Duration(seconds: 10)
// );
// if (location.city == null || location.city == '') //网络不好,定位失败
// {
// // App.sp.setString("lat", "39.684670899");
// // App.sp.setString("lng", "118.17630045");
// } else {
// if (widget.long == null ||
// widget.long == '' ||
// widget.long == 'null') {
// latitude = location.latLng!.latitude;
// longitude = location.latLng!.longitude;
// if (_controller != null) {
// _controller!.setCenterCoordinate(LatLng(
// location.latLng!.latitude, location.latLng!.longitude));
// }
// page = 1;
// _loadData(
// LatLng(location.latLng!.latitude, location.latLng!.longitude));
// setState(() {});
// }
// latitudeLocation = location.latLng!.latitude;
// longitudeLocation = location.latLng!.longitude;
// }
});
} else {
//无权限
}
}
// 开始定位
/// 设置定位参数并启动定位
void _startLocation() {
/// 开始定位之前设置定位参数
_setLocationOption();
_locationPlugin.startLocation();
}
/// 停止定位
/// 停止定位服务
void _stopLocation() {
_locationPlugin.stopLocation();
}
void onMapCreated(AMapController controller) {
// setState(() {
_mapController = controller;
// _mapController.moveCamera(
// CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),
// animated: true,
// );
// getApprovalNumber();
// });
}
/// 获取审图号
// void getApprovalNumber() async {
// //普通地图审图号
// String mapContentApprovalNumber =
// (await _mapController.getMapContentApprovalNumber());
// //卫星地图审图号
// String satelliteImageApprovalNumber =
// (await _mapController.getSatelliteImageApprovalNumber());
// print('地图审图号(普通地图): $mapContentApprovalNumber');
// print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
// }
//移动视野
// void _onCameraMove(CameraPosition cameraPosition) {
// latitude = cameraPosition.target.latitude;
// longitude = cameraPosition.target.longitude;
// page = 1;
// _loadData(cameraPosition.target);
// }
//移动地图结束
void _onCameraMoveEnd(CameraPosition cameraPosition) {
setState(() {
_currentZoom = '当前缩放级别:${cameraPosition.zoom}';
});
_mapController.moveCamera(
CameraUpdate.zoomTo(cameraPosition.zoom),
animated: true,
);
latitude = cameraPosition.target.latitude;
longitude = cameraPosition.target.longitude;
page = 1;
_loadData(cameraPosition.target);
}
@override
Widget build(BuildContext context) {
final AMapWidget amap = AMapWidget(
initialCameraPosition:
CameraPosition(target: LatLng(latitude, longitude), zoom: 16),
onMapCreated: onMapCreated,
// onCameraMove: _onCameraMove,
onCameraMoveEnd: _onCameraMoveEnd,
minMaxZoomPreference: MinMaxZoomPreference(_minZoom, _maxZoom),
scaleEnabled: true,
);
return Scaffold(
resizeToAvoidBottomInset: false, //防止底部布局被顶起
appBar: SystemAppBar(
'选择位置信息',
onTap: () {
if (Navigator.canPop(context)) {
Navigator.pop(context);
}
},
),
body: Column(
children: <Widget>[
// Theme(
// data: new
// ThemeData(
// // primaryColor: MyColours.color_438E93,
// // hintColor: MyColours.color_438E93),
// child:
// Container(
// color: MyColours.color_438E93,
// decoration: BoxDecoration(
// color: MyColours.color_438E93,
// boxShadow: [
// BoxShadow(color: Colors.white, spreadRadius: 1),
// ],
// ),
// padding: EdgeInsets.all(5),
// child:
// ),
// ),
// ListView.builder(
// shrinkWrap: true,
// itemCount: inputTipDatas.length,
// itemBuilder: (context, index) {
// InputTip inputTip = inputTipDatas[index];
// return InkWell(
// onTap: () {
// // searchAroundAddress(inputTip.name ?? '');
// // searchPoiId(inputTip.poiId ?? '');
// // _loadData(inputTip.coordinate ??
// // LatLng(latitude, longitude));
// },
// child: Container(
// child: Row(
// children: [
// Text(
// inputTip.name ?? '',
// style: TextStyle(
// fontSize: font(15),
// color: MyColours.color_515151),
// ),
// HEmptyView(10),
// Expanded(
// child: Text(
// (inputTip.district ?? '') +
// (inputTip.address ?? ''),
// style: TextStyle(
// fontSize: font(13),
// color: MyColours.color_999999),
// ),
// ),
// ],
// )));
// })
// ],
// ),
Stack(
children: [
Container(
height: w(300),
child: Stack(
children: <Widget>[
amap,
// AmapView(
// showZoomControl: false,
// /// 是否显示指南针控件
// showCompass: true,
// /// 是否显示比例尺控件
// showScaleControl: true,
// /// 是否使能缩放手势
// zoomGesturesEnabled: true,
// /// 是否使能滚动手势
// scrollGesturesEnabled: true,
// /// 是否使能旋转手势
// rotateGestureEnabled: false,
// centerCoordinate: LatLng(latitude, longitude),
// maskDelay: Duration(milliseconds: 500),
// zoomLevel: 19,
// onMapCreated: (controller) async {
// _controller = controller;
// _controller!
// .setCenterCoordinate(LatLng(latitude, longitude));
// // if (await requestPermission(PermissionGroup.location)) {
// // await controller.showMyLocation(true);
// // await controller?.showLocateControl(true);
// // final latLng = await _controller?.getLocation(
// // delay: Duration(seconds: 2));
// // await enableFluttifyLog(false); // 关闭log
// // _loadData(latLng);
// // } else {
// // //无权限
// // _showLocPemWidget();
// // }
// },
// // markers: [],
// onMapMoveEnd: (MapMove move) async {
// latitude = move.coordinate!.latitude;
// longitude = move.coordinate!.longitude;
// page = 1;
// _loadData(move.coordinate!);
// },
// ),
Center(
child: Icon(
Icons.place,
size: w(32),
color: Color(0xFFFF0000),
),
),
Positioned(
right: w(10),
bottom: w(10),
child: InkWell(
onTap: () {
_mapController.moveCamera(
CameraUpdate.newLatLng(
LatLng(latitudeLocation, longitudeLocation)),
animated: true,
);
},
child: Container(
decoration: BoxDecoration(
color: MyColours.color_ffffff,
borderRadius: BorderRadius.circular(r(5))),
padding: EdgeInsets.all(w(5)),
child: Image.asset(
Utils.getImgPath('location_map'),
width: w(25),
),
)),
)
],
),
),
Positioned(
top: w(10),
left: w(20),
right: w(20),
child: Container(
// height: w(45),
padding: EdgeInsets.symmetric(vertical: w(10)),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(r(10))),
child: TextField(
textAlignVertical: TextAlignVertical.center,
style: TextStyle(
color: MyColours.color_515151,
fontSize: font(15),
),
controller:
TextEditingController.fromValue(TextEditingValue(
// 设置内容
text: keyword,
selection: TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream,
offset: keyword.length)),
// 保持光标在最后
)),
decoration: InputDecoration(
// border: b,
// border: OutlineInputBorder(
// borderRadius: BorderRadius.all(Radius.circular(40)),
// ),
border: OutlineInputBorder(borderSide: BorderSide.none),
hintText: '输入关键字',
isCollapsed: true,
hintStyle: TextStyle(
color: MyColours.color_999999, fontSize: font(15)),
// contentPadding: const EdgeInsets.symmetric(
// vertical: 8, horizontal: 1),
prefixIconConstraints: BoxConstraints(maxWidth: w(40)),
prefixIcon: Padding(
padding: EdgeInsets.only(left: w(10), right: w(10)),
child: SizedBox(
width: w(30),
child: Image.asset(
Utils.getImgPath('search_black'),
))),
suffixIconConstraints: BoxConstraints(maxWidth: w(32)),
suffixIcon: InkWell(
child: Padding(
padding: EdgeInsets.only(left: w(10), right: w(10)),
child: SizedBox(
width: w(22),
child: Image.asset(
Utils.getImgPath('delete_black'),
))),
onTap: () {
keyword = "";
setState(() {});
},
),
fillColor: Colors.white,
filled: true,
),
inputFormatters: [],
//内容改变的回调
onChanged: (text) {
print('change $text');
keyword = text;
//搜索
if (text != null && text.trim().length > 0) {
JhCommonUtils.debounce(
() => _fetchInputTips(text.toString()));
}
},
//内容提交(按回车)的回调
onSubmitted: (text) {
print('submit $text');
// 触发关闭弹出来的键盘。
keyword = text;
FocusScope.of(context).requestFocus(FocusNode());
setState(() {
// isloading = true;
});
// _fetchInputTips(text.toString());
// searchAroundAddress(text.toString());
},
//按回车时调用
onEditingComplete: () {
print('onEditingComplete');
},
),
),
)
],
),
Expanded(
flex: 1,
child: Visibility(
visible: !isloading,
maintainSize: false,
maintainSemantics: false,
maintainInteractivity: false,
replacement: Center(
child: CupertinoActivityIndicator(),
),
child: EasyRefresh.custom(
controller: refreshController,
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int position) {
print("itemBuilder" + list.length.toString());
PoiModel item = list[position]!;
return InkWell(
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 8, bottom: 5, left: 10),
child: Row(
children: <Widget>[
Icon(
Icons.place,
size: 20.0,
color: position == 0
? Colors.green
: Colors.grey,
),
Expanded(
child: Text(item.title,
style: TextStyle(
fontSize: 16,
color: position == 0
? Colors.green
: Color(0xFF787878))))
],
),
),
Container(
margin: EdgeInsets.only(
top: 5, bottom: 5, left: 18),
alignment: Alignment.centerLeft,
child: Text(
item.address!,
style: TextStyle(
fontSize: 14,
color: Color(0xFF646464),
),
),
),
Divider(
height: 1,
)
],
),
onTap: () async {
// await _controller.setCenterCoordinate(
// LatLng(item.latLng.latitude, item.latLng.longitude),
// zoomLevel: 16);
if (Navigator.canPop(context)) {
Navigator.pop(context, {
'address': item.address,
'lat': item.latLng!.latitude.toString(),
'lng': item.latLng!.longitude.toString()
});
}
},
);
},
childCount: list.length,
),
)
],
onRefresh: () async {
if (flag) {
page = 1;
_loadData(LatLng(latitude, longitude));
}
},
onLoad: () async {
if (flag) {
page++;
_loadData(LatLng(latitude, longitude),
showloading: false);
}
},
)),
),
],
),
);
}
_fetchInputTips(String text) async {
flag = false;
page = 1;
// setState(() {
// isloading = true;
// });
/// 逆地理编码(坐标转地址)
///
///
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
LatLng latLng = LatLng(latitude, longitude);
address = await _locationPlugin
.onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
List<dynamic> temp = await _locationPlugin.doInputtipsRequest(
text,
city: "",
);
inputTipDatas = [];
temp.forEach((element) {
inputTipDatas.add(MapInputsModel.fromJson(element));
});
print(inputTipDatas);
poiModel = new PoiModel("当前位置", address, latLng);
list.clear();
list.add(poiModel);
for (var inputTip in inputTipDatas) {
String? title = await inputTip.name ?? '';
String? cityStr = (inputTip.district ?? '') + (inputTip.city ?? '');
// LatLng? latLng = await inputTip.point;
list.add(new PoiModel(title.toString(), cityStr, latLng));
}
print(list);
setState(() {
// isloading = false;
});
}
void _loadData(LatLng latLng, {showloading = true}) async {
flag = true;
setState(() {
if (showloading) {
isloading = true;
}
});
/// 逆地理编码(坐标转地址)
///
///
///
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
if (page == 1) {
address = await _locationPlugin
.onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);
poiModel = new PoiModel("当前位置", address, latLng);
list.clear();
list.add(poiModel);
}
// final poiList
List<dynamic> temp = await _locationPlugin.poiSearchAround(
keyword, latLng.longitude, latLng.latitude);
List<MapRoundSearchModel> searchData = [];
temp.forEach((element) {
searchData.add(MapRoundSearchModel.fromJson(element));
});
print(searchData);
for (var poi in searchData) {
String? title = await poi.title;
String? cityName = await poi.cityName;
String? provinceName = await poi.provinceName;
String? snippet = await poi.snippet;
String? adName = await poi.adName;
LatLng? latLng = LatLng(poi.latitude ?? 0, poi.longitude ?? 0);
String? bussniss = poi.businessArea;
list.add(new PoiModel(
title.toString(),
provinceName.toString() +
cityName.toString() +
adName.toString() +
// address.toString() +
bussniss.toString() +
snippet.toString(),
latLng));
}
setState(() {
if (showloading) {
isloading = false;
}
});
}
// void searchPoiId(String text) async {
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// Poi? poi = await AmapSearch.instance.searchPoiId(
// text,
// );
// print(poi);
// }
// void searchAroundAddress(String text) async {
// await AmapLocation.instance.updatePrivacyShow(true);
// await AmapLocation.instance.updatePrivacyAgree(true);
// final poiList = await AmapSearch.instance.searchKeyword(
// text,
// city: "",
// );
// // final poiList = await AmapSearch.instance.searchAround(
// // LatLng(latitude, longitude),
// // city: "",
// // radius: 100000000000000
// // );
// list.clear();
// list.add(poiModel);
// for (var poi in poiList) {
// String? title = await poi.title;
// LatLng? latLng = await poi.latLng;
// String? cityName = await poi.cityName;
// String? provinceName = await poi.provinceName;
// String? address = await poi.address;
// list.add(new PoiModel(
// title.toString(),
// provinceName.toString() + cityName.toString() + address.toString(),
// latLng));
// }
// setState(() {
// isloading = false;
// FocusScope.of(context).requestFocus(FocusNode());
// });
// }
}
class PoiModel {
LatLng? latLng;
String title;
String? address;
PoiModel(this.title, this.address, this.latLng);
}
// import 'package:flutter_easyrefresh/easy_refresh.dart';
// import 'package:one_key/pages/create_store/const_config.dart';
// import 'package:one_key/pages/create_store/map_inputs_model.dart';
// import 'package:one_key/res/colors.dart';
// import 'package:one_key/utils/common_utils.dart';
// import 'package:one_key/utils/misc.dart';
// import 'package:one_key/utils/screen_util.dart';
// import 'package:one_key/utils/utils.dart';
// import 'package:one_key/widgets/system_app_bar.dart';
// import 'package:permission_handler/permission_handler.dart';
// // import '../../utils/common_utils.dart';
// // import 'package:demo/resources/custom_text_style.dart';
// // import 'package:demo/utils/misc.dart';
// // import 'package:demo/widgets/network_state/page_loading.dart';
// class MapChoicePointPage extends StatefulWidget {
// final String? long;
// final String? lat;
// MapChoicePointPage({Key? key, this.long, this.lat}) : super(key: key);
// @override
// _MapChoicePointPageState createState() => _MapChoicePointPageState();
// }
// class _MapChoicePointPageState extends State<MapChoicePointPage> {
// late AMapController _mapController;
// final double _minZoom = 3;
// final double _maxZoom = 20;
// String? _currentZoom;
// // List<Poi>? poiList;
// static List<PoiModel?> list = [];
// static List<PoiModel> searchlist = [];
// PoiModel? poiModel;
// String keyword = "";
// String? address = "";
// bool isloading = true;
// double latitude = 39.684670899;
// double longitude = 118.17630045;
// double latitudeLocation = 39.684670899;
// double longitudeLocation = 118.17630045;
// List<MapInputsModel> inputTipDatas = [];
// int page = 1;
// EasyRefreshController refreshController = EasyRefreshController();
// bool flag = true;
// /// 存储定位结果
// Map<String, Object>? _locationResult;
// /// 定位结果监听器
// StreamSubscription<Map<String, Object>>? _locationListener;
// /// 地理位置解析结果监听器
// StreamSubscription<Map<String, Object>>? _geocodeSearchListener;
// /// 高德定位插件实例
// final AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();
// @override
// void initState() {
// super.initState();
// if (widget.long != null && widget.long != '' && widget.long != 'null') {
// longitude = double.parse(widget.long!);
// }
// if (widget.lat != null && widget.lat != '' && widget.lat != 'null') {
// latitude = double.parse(widget.lat!);
// }
// WidgetsBinding.instance.addPostFrameCallback((_) async {
// AMapInitializer.init(context, apiKey: ConstConfig.amapApiKeys);
// AMapInitializer.updatePrivacyAgree(ConstConfig.amapPrivacyStatement);
// AMapFlutterLocation.setApiKey("1dbf56e2e8a4d0e4cdc2df9efd36bc71",
// "dfb64c0463cb53927914364b5c09aba0",
// ohosKey: "7c2081e92ec65bfffa2df0a5464f0c7b");
// /// 设置是否已经包含高德隐私政策并弹窗展示显示用户查看,如果未包含或者没有弹窗展示,高德定位SDK将不会工作
// ///
// /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
// /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
// ///
// /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
// ///
// /// [hasContains] 隐私声明中是否包含高德隐私政策说明
// ///
// /// [hasShow] 隐私权政策是否弹窗展示告知用户
// AMapFlutterLocation.updatePrivacyShow(true, true);
// /// 设置是否已经取得用户同意,如果未取得用户同意,高德定位SDK将不会工作
// ///
// /// 高德SDK合规使用方案请参考官网地址:https://lbs.amap.com/news/sdkhgsy
// ///
// /// <b>必须保证在调用定位功能之前调用, 建议首次启动App时弹出《隐私政策》并取得用户同意</b>
// ///
// /// [hasAgree] 隐私权政策是否已经取得用户同意
// AMapFlutterLocation.updatePrivacyAgree(true);
// _requestLocationPermission();
// // ama
// // let marker = new AMap.Marker({//添加标记点
// // position: this.position,
// // map: map
// });
// _geocodeSearchListener = _locationPlugin
// .onGeocodeSearchChange()
// .listen((Map<String, Object> result) {
// // setState(() {
// if (result.containsKey('errorCode')) {
// Utils.showToast(result['errorInfo'].toString());
// } else {
// _locationResult = result;
// print(_locationResult);
// }
// });
// /// 注册定位结果监听
// /// 通过监听器接收定位结果并更新UI
// _locationListener = _locationPlugin
// .onLocationChanged()
// .listen((Map<String, Object> result) {
// // setState(() {
// if (result.containsKey('errorCode')) {
// Utils.showToast(result['errorInfo'].toString());
// } else {
// _locationResult = result;
// print(_locationResult);
// if (result['latitude'] == null || result['latitude'] == '') //网络不好,定位失败
// {
// // App.sp.setString("lat", "39.684670899");
// // App.sp.setString("lng", "118.17630045");
// } else {
// if (widget.long == null ||
// widget.long == '' ||
// widget.long == 'null') {
// latitude = double.parse(result['latitude'].toString());
// longitude = double.parse(result['longitude'].toString());
// // if (_mapController != null) {
// _mapController.moveCamera(
// CameraUpdate.newLatLng(LatLng(latitude, longitude)));
// // }
// page = 1;
// // _loadData(LatLng(latitude, longitude));
// // setState(() {});
// }
// latitudeLocation = latitude;
// longitudeLocation = longitude;
// _mapController.moveCamera(
// CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),
// animated: true,
// );
// _loadData(LatLng(latitude, longitude));
// }
// }
// });
// }
// @override
// void dispose() {
// super.dispose();
// /// 移除定位监听
// /// 防止内存泄漏
// if (null != _locationListener) {
// _locationListener?.cancel();
// }
// if (null != _geocodeSearchListener) {
// _geocodeSearchListener?.cancel();
// }
// /// 销毁定位
// /// 释放定位资源
// _locationPlugin.destroy();
// }
// // Future<bool> checkLocationPermission() async {
// // PermissionStatus permissionStatus = await Permission.location.status;
// // if (permissionStatus == PermissionStatus.granted) {
// // return true;
// // } else {
// // return false;
// // }
// // }
// /// 检查权限并定
// // _getLocationPermission() async {
// // if (!(await checkPermission(Permission.location))) {
// // //没有定位权限
// // //申请定位权限
// // _requestLocationPermission();
// // } else {
// // //去定位
// // _requestLocationPermission();
// // }
// // }
// /// 设置定位参数
// /// 配置定位选项,如精度、频率等
// void _setLocationOption() {
// AMapLocationOption locationOption = new AMapLocationOption();
// /// 是否单次定位
// /// false表示连续定位
// locationOption.onceLocation = true;
// /// 是否需要返回逆地理信息
// /// true表示需要返回地址信息
// locationOption.needAddress = true;
// /// 是否需要返回逆地理编码信息
// locationOption.locatingWithReGeocode = true;
// /// 逆地理信息的语言类型
// /// 默认为自动适配当前系统语言
// locationOption.geoLanguage = GeoLanguage.DEFAULT;
// /// iOS 14定位精度权限设置
// /// 设置为模糊定位精度
// locationOption.desiredLocationAccuracyAuthorizationMode =
// AMapLocationAccuracyAuthorizationMode.ReduceAccuracy;
// /// iOS 14精确定位目的key
// /// 需要与info.plist中配置一致
// locationOption.fullAccuracyPurposeKey = "AMapLocationScene";
// /// 设置Android端连续定位的定位间隔
// /// 单位:毫秒
// locationOption.locationInterval = 2000;
// /// 设置Android端的定位模式
// /// 可选值:
// /// [AMapLocationMode.Battery_Saving] 低功耗模式
// /// [AMapLocationMode.Device_Sensors] 仅设备模式
// /// [AMapLocationMode.Hight_Accuracy] 高精度模式
// locationOption.locationMode = AMapLocationMode.Hight_Accuracy;
// /// 设置iOS端的定位最小更新距离
// /// -1表示不限制距离
// locationOption.distanceFilter = -1;
// /// 设置iOS端期望的定位精度
// /// 可选值:
// /// [DesiredAccuracy.Best] 最高精度
// /// [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度
// /// [DesiredAccuracy.NearestTenMeters] 10米
// /// [DesiredAccuracy.Kilometer] 1000米
// /// [DesiredAccuracy.ThreeKilometers] 3000米
// locationOption.desiredAccuracy = DesiredAccuracy.Best;
// /// 设置iOS端是否允许系统暂停定位
// /// false表示不允许系统暂停定位
// locationOption.pausesLocationUpdatesAutomatically = false;
// /// 将定位参数设置给定位插件
// _locationPlugin.setLocationOption(locationOption);
// }
// /// 获取定位权限
// _requestLocationPermission() async {
// /// [hasShow] 隐私权政策是否弹窗展示告知用户
// AMapFlutterLocation.updatePrivacyShow(true, true);
// /// [hasAgree] 隐私权政策是否已经取得用户同意
// AMapFlutterLocation.updatePrivacyAgree(true);
// // await AMapFlutterLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// bool canLocation = false;
// if (!(await checkPermission(Permission.location))) {
// //没有定位权限
// //申请定位权限
// canLocation = await requestPermission(Permission.location);
// } else {
// canLocation = true;
// }
// // bool canLocation = await requestPermission(Permission.location);
// // 单次定位
// if (canLocation) {
// Future.delayed(Duration(milliseconds: 200), () async {
// /// [hasShow] 隐私权政策是否弹窗展示告知用户
// AMapFlutterLocation.updatePrivacyShow(true, true);
// /// [hasAgree] 隐私权政策是否已经取得用户同意
// AMapFlutterLocation.updatePrivacyAgree(true);
// _startLocation();
// // final location = await AmapLocation.instance.fetchLocation(
// // // needAddress: true,
// // // mode: LocationAccuracy.High,
// // // timeout: Duration(seconds: 10)
// // );
// // if (location.city == null || location.city == '') //网络不好,定位失败
// // {
// // // App.sp.setString("lat", "39.684670899");
// // // App.sp.setString("lng", "118.17630045");
// // } else {
// // if (widget.long == null ||
// // widget.long == '' ||
// // widget.long == 'null') {
// // latitude = location.latLng!.latitude;
// // longitude = location.latLng!.longitude;
// // if (_controller != null) {
// // _controller!.setCenterCoordinate(LatLng(
// // location.latLng!.latitude, location.latLng!.longitude));
// // }
// // page = 1;
// // _loadData(
// // LatLng(location.latLng!.latitude, location.latLng!.longitude));
// // setState(() {});
// // }
// // latitudeLocation = location.latLng!.latitude;
// // longitudeLocation = location.latLng!.longitude;
// // }
// });
// } else {
// //无权限
// }
// }
// // 开始定位
// /// 设置定位参数并启动定位
// void _startLocation() {
// /// 开始定位之前设置定位参数
// _setLocationOption();
// _locationPlugin.startLocation();
// }
// /// 停止定位
// /// 停止定位服务
// void _stopLocation() {
// _locationPlugin.stopLocation();
// }
// void onMapCreated(AMapController controller) {
// // setState(() {
// _mapController = controller;
// // _mapController.moveCamera(
// // CameraUpdate.newLatLng(LatLng(latitudeLocation, longitudeLocation)),
// // animated: true,
// // );
// // getApprovalNumber();
// // });
// }
// /// 获取审图号
// // void getApprovalNumber() async {
// // //普通地图审图号
// // String mapContentApprovalNumber =
// // (await _mapController.getMapContentApprovalNumber());
// // //卫星地图审图号
// // String satelliteImageApprovalNumber =
// // (await _mapController.getSatelliteImageApprovalNumber());
// // print('地图审图号(普通地图): $mapContentApprovalNumber');
// // print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
// // }
// //移动视野
// // void _onCameraMove(CameraPosition cameraPosition) {
// // latitude = cameraPosition.target.latitude;
// // longitude = cameraPosition.target.longitude;
// // page = 1;
// // _loadData(cameraPosition.target);
// // }
// //移动地图结束
// void _onCameraMoveEnd(CameraPosition cameraPosition) {
// setState(() {
// _currentZoom = '当前缩放级别:${cameraPosition.zoom}';
// });
// _mapController.moveCamera(
// CameraUpdate.zoomTo(cameraPosition.zoom),
// animated: true,
// );
// latitude = cameraPosition.target.latitude;
// longitude = cameraPosition.target.longitude;
// page = 1;
// _loadData(cameraPosition.target);
// }
// @override
// Widget build(BuildContext context) {
// final AMapWidget amap = AMapWidget(
// initialCameraPosition:
// CameraPosition(target: LatLng(latitude, longitude), zoom: 16),
// onMapCreated: onMapCreated,
// // onCameraMove: _onCameraMove,
// onCameraMoveEnd: _onCameraMoveEnd,
// minMaxZoomPreference: MinMaxZoomPreference(_minZoom, _maxZoom),
// scaleEnabled: true,
// );
// return Scaffold(
// resizeToAvoidBottomInset: false, //防止底部布局被顶起
// appBar: SystemAppBar(
// '选择位置信息',
// onTap: () {
// if (Navigator.canPop(context)) {
// Navigator.pop(context);
// }
// },
// ),
// body: Column(
// children: <Widget>[
// // Theme(
// // data: new
// // ThemeData(
// // // primaryColor: MyColours.color_438E93,
// // // hintColor: MyColours.color_438E93),
// // child:
// // Container(
// // color: MyColours.color_438E93,
// // decoration: BoxDecoration(
// // color: MyColours.color_438E93,
// // boxShadow: [
// // BoxShadow(color: Colors.white, spreadRadius: 1),
// // ],
// // ),
// // padding: EdgeInsets.all(5),
// // child:
// // ),
// // ),
// // ListView.builder(
// // shrinkWrap: true,
// // itemCount: inputTipDatas.length,
// // itemBuilder: (context, index) {
// // InputTip inputTip = inputTipDatas[index];
// // return InkWell(
// // onTap: () {
// // // searchAroundAddress(inputTip.name ?? '');
// // // searchPoiId(inputTip.poiId ?? '');
// // // _loadData(inputTip.coordinate ??
// // // LatLng(latitude, longitude));
// // },
// // child: Container(
// // child: Row(
// // children: [
// // Text(
// // inputTip.name ?? '',
// // style: TextStyle(
// // fontSize: font(15),
// // color: MyColours.color_515151),
// // ),
// // HEmptyView(10),
// // Expanded(
// // child: Text(
// // (inputTip.district ?? '') +
// // (inputTip.address ?? ''),
// // style: TextStyle(
// // fontSize: font(13),
// // color: MyColours.color_999999),
// // ),
// // ),
// // ],
// // )));
// // })
// // ],
// // ),
// Stack(
// children: [
// Container(
// height: w(300),
// child: Stack(
// children: <Widget>[
// amap,
// // AmapView(
// // showZoomControl: false,
// // /// 是否显示指南针控件
// // showCompass: true,
// // /// 是否显示比例尺控件
// // showScaleControl: true,
// // /// 是否使能缩放手势
// // zoomGesturesEnabled: true,
// // /// 是否使能滚动手势
// // scrollGesturesEnabled: true,
// // /// 是否使能旋转手势
// // rotateGestureEnabled: false,
// // centerCoordinate: LatLng(latitude, longitude),
// // maskDelay: Duration(milliseconds: 500),
// // zoomLevel: 19,
// // onMapCreated: (controller) async {
// // _controller = controller;
// // _controller!
// // .setCenterCoordinate(LatLng(latitude, longitude));
// // // if (await requestPermission(PermissionGroup.location)) {
// // // await controller.showMyLocation(true);
// // // await controller?.showLocateControl(true);
// // // final latLng = await _controller?.getLocation(
// // // delay: Duration(seconds: 2));
// // // await enableFluttifyLog(false); // 关闭log
// // // _loadData(latLng);
// // // } else {
// // // //无权限
// // // _showLocPemWidget();
// // // }
// // },
// // // markers: [],
// // onMapMoveEnd: (MapMove move) async {
// // latitude = move.coordinate!.latitude;
// // longitude = move.coordinate!.longitude;
// // page = 1;
// // _loadData(move.coordinate!);
// // },
// // ),
// Center(
// child: Icon(
// Icons.place,
// size: w(32),
// color: Color(0xFFFF0000),
// ),
// ),
// Positioned(
// right: w(10),
// bottom: w(10),
// child: InkWell(
// onTap: () {
// _mapController.moveCamera(
// CameraUpdate.newLatLng(
// LatLng(latitudeLocation, longitudeLocation)),
// animated: true,
// );
// },
// child: Container(
// decoration: BoxDecoration(
// color: MyColours.color_ffffff,
// borderRadius: BorderRadius.circular(r(5))),
// padding: EdgeInsets.all(w(5)),
// child: Image.asset(
// Utils.getImgPath('location_map'),
// width: w(25),
// ),
// )),
// )
// ],
// ),
// ),
// Positioned(
// top: w(10),
// left: w(20),
// right: w(20),
// child: Container(
// // height: w(45),
// padding: EdgeInsets.symmetric(vertical: w(10)),
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(r(10))),
// child: TextField(
// textAlignVertical: TextAlignVertical.center,
// style: TextStyle(
// color: MyColours.color_515151,
// fontSize: font(15),
// ),
// controller:
// TextEditingController.fromValue(TextEditingValue(
// // 设置内容
// text: keyword,
// selection: TextSelection.fromPosition(TextPosition(
// affinity: TextAffinity.downstream,
// offset: keyword.length)),
// // 保持光标在最后
// )),
// decoration: InputDecoration(
// // border: b,
// // border: OutlineInputBorder(
// // borderRadius: BorderRadius.all(Radius.circular(40)),
// // ),
// border: OutlineInputBorder(borderSide: BorderSide.none),
// hintText: '输入关键字',
// isCollapsed: true,
// hintStyle: TextStyle(
// color: MyColours.color_999999, fontSize: font(15)),
// // contentPadding: const EdgeInsets.symmetric(
// // vertical: 8, horizontal: 1),
// prefixIconConstraints: BoxConstraints(maxWidth: w(40)),
// prefixIcon: Padding(
// padding: EdgeInsets.only(left: w(10), right: w(10)),
// child: SizedBox(
// width: w(30),
// child: Image.asset(
// Utils.getImgPath('search_black'),
// ))),
// suffixIconConstraints: BoxConstraints(maxWidth: w(32)),
// suffixIcon: InkWell(
// child: Padding(
// padding: EdgeInsets.only(left: w(10), right: w(10)),
// child: SizedBox(
// width: w(22),
// child: Image.asset(
// Utils.getImgPath('delete_black'),
// ))),
// onTap: () {
// keyword = "";
// setState(() {});
// },
// ),
// fillColor: Colors.white,
// filled: true,
// ),
// inputFormatters: [],
// //内容改变的回调
// onChanged: (text) {
// print('change $text');
// keyword = text;
// //搜索
// if (text != null && text.trim().length > 0) {
// JhCommonUtils.debounce(
// () => _fetchInputTips(text.toString()));
// }
// },
// //内容提交(按回车)的回调
// onSubmitted: (text) {
// print('submit $text');
// // 触发关闭弹出来的键盘。
// keyword = text;
// FocusScope.of(context).requestFocus(FocusNode());
// setState(() {
// // isloading = true;
// });
// // _fetchInputTips(text.toString());
// // searchAroundAddress(text.toString());
// },
// //按回车时调用
// onEditingComplete: () {
// print('onEditingComplete');
// },
// ),
// ),
// )
// ],
// ),
// Expanded(
// flex: 1,
// child: Visibility(
// visible: !isloading,
// maintainSize: false,
// maintainSemantics: false,
// maintainInteractivity: false,
// replacement: Center(
// child: CupertinoActivityIndicator(),
// ),
// child: EasyRefresh.custom(
// controller: refreshController,
// slivers: [
// SliverList(
// delegate: SliverChildBuilderDelegate(
// (BuildContext context, int position) {
// print("itemBuilder" + list.length.toString());
// PoiModel item = list[position]!;
// return InkWell(
// child: Column(
// children: <Widget>[
// Container(
// margin: EdgeInsets.only(
// top: 8, bottom: 5, left: 10),
// child: Row(
// children: <Widget>[
// Icon(
// Icons.place,
// size: 20.0,
// color: position == 0
// ? Colors.green
// : Colors.grey,
// ),
// Expanded(
// child: Text(item.title,
// style: TextStyle(
// fontSize: 16,
// color: position == 0
// ? Colors.green
// : Color(0xFF787878))))
// ],
// ),
// ),
// Container(
// margin: EdgeInsets.only(
// top: 5, bottom: 5, left: 18),
// alignment: Alignment.centerLeft,
// child: Text(
// item.address!,
// style: TextStyle(
// fontSize: 14,
// color: Color(0xFF646464),
// ),
// ),
// ),
// Divider(
// height: 1,
// )
// ],
// ),
// onTap: () async {
// // await _controller.setCenterCoordinate(
// // LatLng(item.latLng.latitude, item.latLng.longitude),
// // zoomLevel: 16);
// if (Navigator.canPop(context)) {
// Navigator.pop(context, {
// 'address': item.address,
// 'lat': item.latLng!.latitude.toString(),
// 'lng': item.latLng!.longitude.toString()
// });
// }
// },
// );
// },
// childCount: list.length,
// ),
// )
// ],
// onRefresh: () async {
// if (flag) {
// page = 1;
// _loadData(LatLng(latitude, longitude));
// }
// },
// onLoad: () async {
// if (flag) {
// page++;
// _loadData(LatLng(latitude, longitude),
// showloading: false);
// }
// },
// )),
// ),
// ],
// ),
// );
// }
// _fetchInputTips(String text) async {
// flag = false;
// page = 1;
// // setState(() {
// // isloading = true;
// // });
// /// 逆地理编码(坐标转地址)
// ///
// ///
// // await AmapLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// LatLng latLng = LatLng(latitude, longitude);
// address = await _locationPlugin
// .onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);
// // await AmapLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// List<dynamic> temp = await _locationPlugin.doInputtipsRequest(
// text,
// city: "",
// );
// inputTipDatas = [];
// temp.forEach((element) {
// inputTipDatas.add(MapInputsModel.fromJson(element));
// });
// print(inputTipDatas);
// poiModel = new PoiModel("当前位置", address, latLng);
// list.clear();
// list.add(poiModel);
// for (var inputTip in inputTipDatas) {
// String? title = await inputTip.name ?? '';
// String? cityStr = (inputTip.district ?? '') + (inputTip.city ?? '');
// // LatLng? latLng = await inputTip.point;
// list.add(new PoiModel(title.toString(), cityStr, latLng));
// }
// print(list);
// setState(() {
// // isloading = false;
// });
// }
// void _loadData(LatLng latLng, {showloading = true}) async {
// flag = true;
// setState(() {
// if (showloading) {
// isloading = true;
// }
// });
// /// 逆地理编码(坐标转地址)
// ///
// ///
// ///
// // await AmapLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// if (page == 1) {
// address = await _locationPlugin
// .onGeocodeSearch(true, [latLng.longitude, latLng.latitude]);
// poiModel = new PoiModel("当前位置", address, latLng);
// list.clear();
// list.add(poiModel);
// }
// // final poiList
// List<dynamic> temp = await _locationPlugin.poiSearchAround(
// keyword, latLng.longitude, latLng.latitude);
// List<MapRoundSearchModel> searchData = [];
// temp.forEach((element) {
// searchData.add(MapRoundSearchModel.fromJson(element));
// });
// print(searchData);
// for (var poi in searchData) {
// String? title = await poi.title;
// String? cityName = await poi.cityName;
// String? provinceName = await poi.provinceName;
// String? snippet = await poi.snippet;
// String? adName = await poi.adName;
// LatLng? latLng = LatLng(poi.latitude ?? 0, poi.longitude ?? 0);
// String? bussniss = poi.businessArea;
// list.add(new PoiModel(
// title.toString(),
// provinceName.toString() +
// cityName.toString() +
// adName.toString() +
// // address.toString() +
// bussniss.toString() +
// snippet.toString(),
// latLng));
// }
// setState(() {
// if (showloading) {
// isloading = false;
// }
// });
// }
// // void searchPoiId(String text) async {
// // await AmapLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// // Poi? poi = await AmapSearch.instance.searchPoiId(
// // text,
// // );
// // print(poi);
// // }
// // void searchAroundAddress(String text) async {
// // await AmapLocation.instance.updatePrivacyShow(true);
// // await AmapLocation.instance.updatePrivacyAgree(true);
// // final poiList = await AmapSearch.instance.searchKeyword(
// // text,
// // city: "",
// // );
// // // final poiList = await AmapSearch.instance.searchAround(
// // // LatLng(latitude, longitude),
// // // city: "",
// // // radius: 100000000000000
// // // );
// // list.clear();
// // list.add(poiModel);
// // for (var poi in poiList) {
// // String? title = await poi.title;
// // LatLng? latLng = await poi.latLng;
// // String? cityName = await poi.cityName;
// // String? provinceName = await poi.provinceName;
// // String? address = await poi.address;
// // list.add(new PoiModel(
// // title.toString(),
// // provinceName.toString() + cityName.toString() + address.toString(),
// // latLng));
// // }
// // setState(() {
// // isloading = false;
// // FocusScope.of(context).requestFocus(FocusNode());
// // });
// // }
// }
// class PoiModel {
// LatLng? latLng;
// String title;
// String? address;
// PoiModel(this.title, this.address, this.latLng);
// }
... ...
// import 'package:flutter/material.dart';
// import 'package:speech_to_text/speech_recognition_result.dart';
// import 'package:speech_to_text/speech_to_text.dart' as stt;
// class MyTestPage extends StatefulWidget {
// MyTestPage({Key? key}) : super(key: key);
// @override
// _MyTestPageState createState() => _MyTestPageState();
// }
// class _MyTestPageState extends State<MyTestPage> {
// SpeechToText _speechToText = SpeechToText();
// bool _speechEnabled = false;
// String _lastWords = '';
// @override
// void initState() {
// super.initState();
// _initSpeech();
// }
// /// This has to happen only once per app
// void _initSpeech() async {
// _speechEnabled = await _speechToText.initialize();
// setState(() {});
// }
// /// Each time to start a speech recognition session
// void _startListening() async {
// await _speechToText.listen(onResult: _onSpeechResult);
// setState(() {});
// }
// /// Manually stop the active speech recognition session
// /// Note that there are also timeouts that each platform enforces
// /// and the SpeechToText plugin supports setting timeouts on the
// /// listen method.
// void _stopListening() async {
// await _speechToText.stop();
// setState(() {});
// }
// /// This is the callback that the SpeechToText plugin calls when
// /// the platform returns recognized words.
// void _onSpeechResult(SpeechRecognitionResult result) {
// setState(() {
// _lastWords = result.recognizedWords;
// });
// }
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(
// title: Text('Speech Demo'),
// ),
// body: Center(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// Container(
// padding: EdgeInsets.all(16),
// child: Text(
// 'Recognized words:',
// style: TextStyle(fontSize: 20.0),
// ),
// ),
// Expanded(
// child: Container(
// padding: EdgeInsets.all(16),
// child: Text(
// // If listening is active show the recognized words
// _speechToText.isListening
// ? '$_lastWords'
// // If listening isn't active but could be tell the user
// // how to start it, otherwise indicate that speech
// // recognition is not yet ready or not supported on
// // the target device
// : _speechEnabled
// ? 'Tap the microphone to start listening...'
// : 'Speech not available',
// ),
// ),
// ),
// ],
// ),
// ),
// floatingActionButton: FloatingActionButton(
// onPressed:
// // If not yet listening for speech start, otherwise stop
// _speechToText.isNotListening ? _startListening : _stopListening,
// tooltip: 'Listen',
// child: Icon(_speechToText.isNotListening ? Icons.mic_off : Icons.mic),
// ),
// );
// }
// }
\ No newline at end of file
... ...
// import 'dart:async';
// import 'package:flutter/material.dart';
// import 'package:one_key/pages/home/RecognitionResultsWidget.dart';
// import 'package:provider/provider.dart';
// import 'package:speech_to_text/speech_to_text.dart';
// import 'package:speech_to_text/speech_to_text_provider.dart';
// class ProviderDemoApp extends StatefulWidget {
// const ProviderDemoApp({super.key});
// @override
// State<ProviderDemoApp> createState() => _ProviderDemoAppState();
// }
// class _ProviderDemoAppState extends State<ProviderDemoApp> {
// final SpeechToText speech = SpeechToText();
// late SpeechToTextProvider speechProvider;
// @override
// void initState() {
// super.initState();
// speechProvider = SpeechToTextProvider(speech);
// initSpeechState();
// }
// Future<void> initSpeechState() async {
// bool ggggg = await speechProvider.initialize();
// print(ggggg);
// }
// @override
// Widget build(BuildContext context) {
// return ChangeNotifierProvider<SpeechToTextProvider>.value(
// value: speechProvider,
// child: MaterialApp(
// home: Scaffold(
// appBar: AppBar(
// title: const Text('标题'),
// ),
// body: const SpeechProviderExampleWidget(),
// ),
// ),
// );
// }
// }
// class SpeechProviderExampleWidget extends StatefulWidget {
// const SpeechProviderExampleWidget({super.key});
// @override
// SpeechProviderExampleWidgetState createState() =>
// SpeechProviderExampleWidgetState();
// }
// class SpeechProviderExampleWidgetState
// extends State<SpeechProviderExampleWidget> {
// String _currentLocaleId = '';
// void _setCurrentLocale(SpeechToTextProvider speechProvider) {
// if (speechProvider.isAvailable && _currentLocaleId.isEmpty) {
// _currentLocaleId = speechProvider.systemLocale?.localeId ?? '';
// }
// }
// @override
// Widget build(BuildContext context) {
// var speechProvider = Provider.of<SpeechToTextProvider>(context);
// if (speechProvider.isNotAvailable) {
// return const Center(
// child: Text(
// 'Speech recognition not available, no permission or not available on the device.'),
// );
// }
// _setCurrentLocale(speechProvider);
// return Column(children: [
// const Center(
// child: Text(
// 'Speech recognition available',
// style: TextStyle(fontSize: 22.0),
// ),
// ),
// Column(
// children: <Widget>[
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// children: <Widget>[
// TextButton(
// onPressed:
// !speechProvider.isAvailable || speechProvider.isListening
// ? null
// : () => speechProvider.listen(
// partialResults: true, localeId: _currentLocaleId),
// child: const Text('Start'),
// ),
// TextButton(
// onPressed: speechProvider.isListening
// ? () => speechProvider.stop()
// : null,
// child: const Text('Stop'),
// ),
// TextButton(
// onPressed: speechProvider.isListening
// ? () => speechProvider.cancel()
// : null,
// child: const Text('Cancel'),
// ),
// ],
// ),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// children: <Widget>[
// DropdownButton(
// onChanged: (selectedVal) => _switchLang(selectedVal),
// value: _currentLocaleId,
// items: speechProvider.locales
// .map(
// (localeName) => DropdownMenuItem(
// value: localeName.localeId,
// child: Text(localeName.name),
// ),
// )
// .toList(),
// ),
// ],
// )
// ],
// ),
// const Expanded(
// flex: 4,
// child: RecognitionResultsWidget(),
// ),
// Expanded(
// flex: 1,
// child: Column(
// children: <Widget>[
// const Center(
// child: Text(
// 'Error Status',
// style: TextStyle(fontSize: 22.0),
// ),
// ),
// Center(
// child: speechProvider.hasError
// ? Text(speechProvider.lastError!.errorMsg)
// : Container(),
// ),
// ],
// ),
// ),
// Container(
// padding: const EdgeInsets.symmetric(vertical: 20),
// color: Theme.of(context).colorScheme.surface,
// child: Center(
// child: speechProvider.isListening
// ? const Text(
// "I'm listening...",
// style: TextStyle(fontWeight: FontWeight.bold),
// )
// : const Text(
// 'Not listening',
// style: TextStyle(fontWeight: FontWeight.bold),
// ),
// ),
// ),
// ]);
// }
// void _switchLang(selectedVal) {
// setState(() {
// _currentLocaleId = selectedVal;
// });
// debugPrint(selectedVal);
// }
// }
... ...
// import 'package:flutter/material.dart';
// import 'package:provider/provider.dart';
// import 'package:speech_to_text/speech_to_text_provider.dart';
// /// Show the most recently recognized speech results and use the level
// /// information to animate the microphone.
// ///
// /// Note that the provider is initialized elsewhere and just accessed
// /// here.
// class RecognitionResultsWidget extends StatelessWidget {
// const RecognitionResultsWidget({super.key});
// @override
// Widget build(BuildContext context) {
// var speechProvider = Provider.of<SpeechToTextProvider>(context);
// return Column(
// children: <Widget>[
// const Center(
// child: Text(
// 'Recognized Words',
// style: TextStyle(fontSize: 22.0),
// ),
// ),
// Expanded(
// child: Stack(
// children: <Widget>[
// Container(
// color: Theme.of(context).secondaryHeaderColor,
// child: Center(
// child: Text(
// speechProvider.lastResult?.recognizedWords ?? '',
// textAlign: TextAlign.center,
// ),
// ),
// ),
// Positioned.fill(
// bottom: 10,
// child: Align(
// alignment: Alignment.bottomCenter,
// child: Container(
// width: 40,
// height: 40,
// alignment: Alignment.center,
// decoration: BoxDecoration(
// boxShadow: [
// BoxShadow(
// blurRadius: .26,
// spreadRadius: speechProvider.lastLevel * 1.5,
// color: Colors.black.withOpacity(.05))
// ],
// color: Colors.white,
// borderRadius: const BorderRadius.all(Radius.circular(50)),
// ),
// child: IconButton(
// icon: const Icon(Icons.mic),
// onPressed: () {},
// ),
// ),
// ),
// ),
// ],
// ),
// ),
// ],
// );
// }
// }
... ...
/*
* Copyright 2018, 2019, 2020, 2021 Dooboolab.
*
* This file is part of Flutter-Sound.
*
* Flutter-Sound is free software: you can redistribute it and/or modify
* it under the terms of the Mozilla Public License version 2 (MPL2.0),
* as published by the Mozilla organization.
*
* Flutter-Sound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MPL General Public License for more details.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data' show Uint8List;
import 'package:audio_session/audio_session.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart' show DateFormat;
import 'package:flutter_sound/flutter_sound.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'dart:typed_data';
/*
This is a demo of what it is possible to do with Flutter Sound. The code of this demo app is not so simple.
Flutter Sound beginners : you probably should look to [SimplePlayback](fs-ex_simple_playback.html)
and [SimpleRecorder](fs-ex_simple_recorder.html)
The biggest interest of this Demo is that it shows most of the features of Flutter Sound :
* Plays from various media with various codecs
* Records to various media with various codecs
* Pause and Resume control from recording or playback
* Shows how to use a stream for getting the playback \(or recoding\) events
* Shows how to specify a callback function when a playback is terminated,
* Shows how to record to a Stream or playback from a stream
* ...
*/
///
const int cstSAMPLERATE = 8000;
const int cstCHANNELNB = 2;
const int cstBITRATE = 16000;
///
const int cstBLOCKSIZE = 4096;
///
enum Media {
///
file,
///
buffer,
///
asset,
///
stream,
///
remoteExampleFile,
}
///
enum AudioState {
///
isPlaying,
///
isPaused,
///
isStopped,
///
isRecording,
///
isRecordingPaused,
}
/*
///
final exampleAudioFilePathAACAdts =
//'https://filesamples.com/samples/audio/aac/sample1.aac';
'https://www.canardoux.xyz/tau_sound/web_example/sample.aac';
///
final exampleAudioFilePathWave =
'http://5.189.150.137:5000/download_audio/CantinaBand3.wav';
///
final exampleAudioFilePathMP3 =
'https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3';
///
final exampleAudioFilePathOPUS =
'https://whatsapp-inbox-server.clare.ai/api/file/showFile?fileName=data/audios/e3f16eb2-10c3-45c9-b0fa-900c94cbe805.opus&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMWI5YjQ3Zi1jMzBjLTRlZDMtYTFhNy1iNmYxNzRkMWQ1NTYiLCJ1bmlxdWVfbmFtZSI6InZlcm5hbEBjbGFyZS5haSIsIm5hbWVpZCI6InZlcm5hbEBjbGFyZS5haSIsImVtYWlsIjoidmVybmFsQGNsYXJlLmFpIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiRVhURVJOQUxfQURNSU5JU1RSQVRPUiIsImV4cCI6MjUzNDAyMzAwODAwLCJpc3MiOiJDbGFyZV9BSSIsImF1ZCI6IkNsYXJlX0FJIn0.yXVZ3n_lYYvJ1rGyF2mVh-80HuS0EEp7sQepxn9rGcY';
///
final albumArtPath =
'https://file-examples-com.github.io/uploads/2017/10/file_example_PNG_500kB.png';
*/
const albumArtPathRemote =
'https://flutter-sound.canardoux.xyz/web_example/assets/extract/3iob.png';
const albumArtPath =
'https://file-examples-com.github.io/uploads/2017/10/file_example_PNG_500kB.png';
///
class Demo extends StatefulWidget {
const Demo({super.key});
@override
State<Demo> createState() => _MyAppState();
}
class _MyAppState extends State<Demo> {
bool _isRecording = false;
final List<String?> _path = [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
];
List<String> assetSample = [
'assets/samples/sample.aac',
'assets/samples/sample.aac',
'assets/samples/sample.opus',
'assets/samples/sample_opus.caf',
'assets/samples/sample.mp3',
'assets/samples/sample.ogg',
'assets/samples/sample_s16_2ch.raw', // Raw PCM int16
'assets/samples/sample_2ch.wav', // int16 wav stereo
'assets/samples/sample.aiff',
'assets/samples/sample_pcm.caf',
'assets/samples/sample.flac',
'assets/samples/sample.mp4',
'assets/samples/sample.amr', // amrNB
'assets/samples/sample_xxx.amr', // amrWB
'assets/samples/sample_xxx.pcm', // pcm8
'assets/samples/sample_f32_2ch.raw', // Raw pcmFloat32
'', // 'assets/samples/sample_xxx.pcm', // pcmWebM
'assets/samples/sample_opus.webm', // opusWebM
'assets/samples/sample_vorbis.webm', // vorbisWebM
'assets/samples/sample_f32_2ch.wav', // wav Float32 stereo
];
List<String> remoteSample = [
'https://fs-doc.vercel.app/extract/01.aac', // 'assets/samples/sample.aac',
'https://fs-doc.vercel.app/extract/01.aac', // 'assets/samples/sample.aac',
'https://fs-doc.vercel.app/extract/08.opus', // 'assets/samples/sample.opus',
'https://fs-doc.vercel.app/extract/04-opus.caf', // 'assets/samples/sample_opus.caf',
'https://fs-doc.vercel.app/extract/05.mp3', // 'assets/samples/sample.mp3',
'https://fs-doc.vercel.app/extract/07.ogg', // 'assets/samples/sample.ogg',
'https://fs-doc.vercel.app/extract/sample_s16_2ch.pcm', // Raw PCM int16
'https://fs-doc.vercel.app/extract/sample_2ch.wav', // int16 wav stereo
'https://fs-doc.vercel.app/extract/02.aiff', // 'assets/samples/sample.aiff',
'https://fs-doc.vercel.app/extract/01-pcm.caf', // 'assets/samples/sample_pcm.caf',
'https://fs-doc.vercel.app/extract/04.flac', // 'assets/samples/sample.flac',
'https://fs-doc.vercel.app/extract/06.mp4', // 'assets/samples/sample.mp4',
'https://fs-doc.vercel.app/extract/03.amr', // 'assets/samples/sample.amr', // amrNB
'https://fs-doc.vercel.app/extract/03.amr', // 'assets/samples/sample_xxx.amr', // amrWB
'https://fs-doc.vercel.app/extract/09-pcm8.raw', // 'assets/samples/sample_xxx.pcm', // pcm8
'https://fs-doc.vercel.app/extract/sample_f32_2ch.raw', // Raw pcmFloat32
'', // pcmWebM
'https://fs-doc.vercel.app/extract/02-opus.webm', // 'assets/samples/sample_opus.webm', // opusWebM
'https://fs-doc.vercel.app/extract/03-vorbis.webm', // 'assets/samples/sample_vorbis.webm', // vorbisWebM
'https://fs-doc.vercel.app/extract/sample_f32_2ch.wav', // wav Float32 stereo
];
StreamSubscription? _recorderSubscription;
StreamSubscription? _playerSubscription;
StreamSubscription? _recordingDataSubscription;
FlutterSoundPlayer playerModule = FlutterSoundPlayer();
FlutterSoundRecorder recorderModule = FlutterSoundRecorder();
String _recorderTxt = '00:00:00';
String _playerTxt = '00:00:00';
double? _dbLevel;
double sliderCurrentPosition = 0.0;
double maxDuration = 1.0;
Media? _media = Media.remoteExampleFile;
Codec _codec = Codec.aacMP4;
bool? _encoderSupported = true; // Optimist
bool _decoderSupported = true; // Optimist
StreamController<Uint8List>? recordingDataController;
IOSink? sink;
Future<void> _initializeExample() async {
await playerModule.closePlayer();
await playerModule.openPlayer();
await playerModule
.setSubscriptionDuration(const Duration(milliseconds: 10));
await recorderModule
.setSubscriptionDuration(const Duration(milliseconds: 100));
await initializeDateFormatting();
await setCodec(_codec);
}
Future<void> openTheRecorder() async {
if (!kIsWeb) {
var status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw RecordingPermissionException('Microphone permission not granted');
}
}
await recorderModule.openRecorder();
if (!await recorderModule.isEncoderSupported(_codec) && kIsWeb) {
_codec = Codec.opusWebM;
}
}
Future<void> init() async {
await openTheRecorder();
await _initializeExample();
if ((!kIsWeb) && Platform.isAndroid) {
await copyAssets();
}
final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
avAudioSessionCategoryOptions:
AVAudioSessionCategoryOptions.allowBluetooth |
AVAudioSessionCategoryOptions.defaultToSpeaker,
avAudioSessionMode: AVAudioSessionMode.spokenAudio,
avAudioSessionRouteSharingPolicy:
AVAudioSessionRouteSharingPolicy.defaultPolicy,
avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
androidAudioAttributes: const AndroidAudioAttributes(
contentType: AndroidAudioContentType.speech,
flags: AndroidAudioFlags.none,
usage: AndroidAudioUsage.voiceCommunication,
),
androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
androidWillPauseWhenDucked: true,
));
}
Future<void> copyAssets() async {
var dataBuffer =
(await rootBundle.load('assets/canardo.png')).buffer.asUint8List();
var path = '${await playerModule.getResourcePath()}/assets';
if (!await Directory(path).exists()) {
await Directory(path).create(recursive: true);
}
await File('$path/canardo.png').writeAsBytes(dataBuffer);
}
@override
void initState() {
super.initState();
init();
}
void cancelRecorderSubscriptions() {
if (_recorderSubscription != null) {
_recorderSubscription!.cancel();
_recorderSubscription = null;
}
}
void cancelPlayerSubscriptions() {
if (_playerSubscription != null) {
_playerSubscription!.cancel();
_playerSubscription = null;
}
}
void cancelRecordingDataSubscription() {
if (_recordingDataSubscription != null) {
_recordingDataSubscription!.cancel();
_recordingDataSubscription = null;
}
recordingDataController = null;
if (sink != null) {
sink!.close();
sink = null;
}
}
@override
void dispose() {
super.dispose();
cancelPlayerSubscriptions();
cancelRecorderSubscriptions();
cancelRecordingDataSubscription();
releaseFlauto();
}
Future<void> releaseFlauto() async {
try {
await playerModule.closePlayer();
await recorderModule.closeRecorder();
} on Exception {
playerModule.logger.e('Released unsuccessful');
}
}
void startRecorder() async {
try {
// Request Microphone permission if needed
if (!kIsWeb) {
var status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw RecordingPermissionException(
'Microphone permission not granted');
}
}
var path = '';
if (!kIsWeb) {
var tempDir = await getTemporaryDirectory();
path = '${tempDir.path}/flutter_sound${ext[_codec.index]}';
} else {
path = '_flutter_sound${ext[_codec.index]}';
}
if (_media == Media.stream) {
assert(_codec == Codec.pcm16);
if (!kIsWeb) {
var outputFile = File(path);
if (outputFile.existsSync()) {
await outputFile.delete();
}
sink = outputFile.openWrite();
} else {
sink = null; // TODO
}
recordingDataController = StreamController<Uint8List>();
_recordingDataSubscription =
recordingDataController!.stream.listen((buffer) {
sink!.add(buffer);
});
await recorderModule.startRecorder(
toStream: recordingDataController!.sink,
bufferSize: 128,
codec: _codec,
numChannels: cstCHANNELNB,
sampleRate: cstSAMPLERATE, // tSTREAMSAMPLERATE, //tSAMPLERATE,
);
} else {
await recorderModule.startRecorder(
toFile: path,
codec: _codec,
bitRate: cstBITRATE,
numChannels: cstCHANNELNB,
sampleRate:
cstSAMPLERATE, // (_codec == Codec.pcm16) ? tSTREAMSAMPLERATE : tSAMPLERATE,
);
}
recorderModule.logger.d('startRecorder');
_recorderSubscription = recorderModule.onProgress!.listen((e) {
var date = DateTime.fromMillisecondsSinceEpoch(
e.duration.inMilliseconds,
isUtc: true);
var txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
setState(() {
_recorderTxt = txt.substring(0, 8);
_dbLevel = e.decibels;
});
});
setState(() {
_isRecording = true;
_path[_codec.index] = path;
});
} on Exception catch (err) {
recorderModule.logger.e('startRecorder error: $err');
setState(() {
stopRecorder();
_isRecording = false;
cancelRecordingDataSubscription();
cancelRecorderSubscriptions();
});
}
}
void stopRecorder() async {
try {
await recorderModule.stopRecorder();
recorderModule.logger.d('stopRecorder');
cancelRecorderSubscriptions();
cancelRecordingDataSubscription();
} on Exception catch (err) {
recorderModule.logger.d('stopRecorder error: $err');
}
setState(() {
_isRecording = false;
});
}
Future<bool> fileExists(String path) async {
return await File(path).exists();
}
// In this simple example, we just load a file in memory.This is stupid but just for demonstration of startPlayerFromBuffer()
Future<Uint8List?> makeBuffer(String path) async {
try {
if (!await fileExists(path)) return null;
var file = File(path);
file.openRead();
var contents = await file.readAsBytes();
playerModule.logger.i('The file is ${contents.length} bytes long.');
return contents;
} on Exception catch (e) {
playerModule.logger.e(e);
return null;
}
}
void _addListeners() {
cancelPlayerSubscriptions();
_playerSubscription = playerModule.onProgress!.listen((e) {
maxDuration = e.duration.inMilliseconds.toDouble();
if (maxDuration <= 0) maxDuration = 0.0;
sliderCurrentPosition =
min(e.position.inMilliseconds.toDouble(), maxDuration);
if (sliderCurrentPosition < 0.0) {
sliderCurrentPosition = 0.0;
}
var date = DateTime.fromMillisecondsSinceEpoch(e.position.inMilliseconds,
isUtc: true);
var txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
setState(() {
_playerTxt = txt.substring(0, 8);
});
});
}
Future<Uint8List> _readFileByte(String filePath) async {
var myUri = Uri.parse(filePath);
var audioFile = File.fromUri(myUri);
Uint8List bytes;
var b = await audioFile.readAsBytes();
bytes = Uint8List.fromList(b);
playerModule.logger.d('reading of bytes is completed');
return bytes;
}
Future<Uint8List> getAssetData(String path) async {
var asset = await rootBundle.load(path);
return asset.buffer.asUint8List();
}
/*
Future<void> feedHim(String path) async {
var data = await _readFileByte(path);
return await playerModule.feedFromStream(data);
}
*/
final int blockSize = 4096;
Future<void> feedHim(String path) async {
var buffer = await _readFileByte(path);
//var buffer = await getAssetData('assets/samples/sample.pcm');
var lnData = 0;
var totalLength = buffer.length;
while (totalLength > 0 && !playerModule.isStopped) {
var bsize = totalLength > blockSize ? blockSize : totalLength;
await playerModule.feedUint8FromStream(
buffer.sublist(lnData, lnData + bsize)); // await !!!!
lnData += bsize;
totalLength -= bsize;
}
}
Future<void> startPlayer() async {
try {
Uint8List? dataBuffer;
String? audioFilePath;
var codec = _codec;
if (_media == Media.asset) {
dataBuffer = (await rootBundle.load(assetSample[codec.index]))
.buffer
.asUint8List();
} else if (_media == Media.file || _media == Media.stream) {
// Do we want to play from buffer or from file ?
if (kIsWeb || await fileExists(_path[codec.index]!)) {
audioFilePath = _path[codec.index];
}
} else if (_media == Media.buffer) {
// Do we want to play from buffer or from file ?
if (await fileExists(_path[codec.index]!)) {
dataBuffer = await makeBuffer(_path[codec.index]!);
if (dataBuffer == null) {
throw Exception('Unable to create the buffer');
}
}
} else if (_media == Media.remoteExampleFile) {
// We have to play an example audio file loaded via a URL
audioFilePath = remoteSample[_codec.index];
}
if (_media == Media.stream) {
await playerModule.startPlayerFromStream(
codec: Codec.pcm16, //_codec,
numChannels: cstCHANNELNB,
sampleRate: cstSAMPLERATE, // tSTREAMSAMPLERATE, //tSAMPLERATE,
interleaved: true,
bufferSize: 1024,
);
_addListeners();
setState(() {});
await feedHim(audioFilePath!);
//await finishPlayer();
await stopPlayer();
return;
} else {
if (audioFilePath != null) {
await playerModule.startPlayer(
fromURI: audioFilePath,
codec: codec,
numChannels: cstCHANNELNB,
sampleRate: cstSAMPLERATE, // tSTREAMSAMPLERATE,
whenFinished: () {
playerModule.logger.d('Play finished');
setState(() {});
});
} else if (dataBuffer != null) {
if (codec == Codec.pcm16) {
dataBuffer = await flutterSoundHelper.pcmToWaveBuffer(
inputBuffer: dataBuffer,
numChannels: cstCHANNELNB,
sampleRate:
cstSAMPLERATE, //(_codec == Codec.pcm16 && _media == Media.asset) ? 48000 : cstSAMPLERATE,
);
codec = Codec.pcm16WAV;
}
await playerModule.startPlayer(
fromDataBuffer: dataBuffer,
sampleRate: cstSAMPLERATE,
numChannels: cstCHANNELNB,
codec: codec,
whenFinished: () {
playerModule.logger.d('Play finished');
setState(() {});
});
}
}
_addListeners();
setState(() {});
playerModule.logger.d('<--- startPlayer');
} on Exception catch (err) {
playerModule.logger.e('error: $err');
await stopPlayer();
}
}
Future<void> stopPlayer() async {
try {
await playerModule.stopPlayer();
playerModule.logger.d('stopPlayer');
if (_playerSubscription != null) {
await _playerSubscription!.cancel();
_playerSubscription = null;
}
sliderCurrentPosition = 0.0;
} on Exception catch (err) {
playerModule.logger.d('error: $err');
}
setState(() {});
}
void pauseResumePlayer() async {
try {
if (playerModule.isPlaying) {
await playerModule.pausePlayer();
} else {
await playerModule.resumePlayer();
}
} on Exception catch (err) {
playerModule.logger.e('error: $err');
}
setState(() {});
}
void pauseResumeRecorder() async {
try {
if (recorderModule.isPaused) {
await recorderModule.resumeRecorder();
} else {
await recorderModule.pauseRecorder();
assert(recorderModule.isPaused);
}
} on Exception catch (err) {
recorderModule.logger.e('error: $err');
}
setState(() {});
}
Future<void> seekToPlayer(int milliSecs) async {
//playerModule.logger.d('-->seekToPlayer');
try {
if (playerModule.isPlaying) {
await playerModule.seekToPlayer(Duration(milliseconds: milliSecs));
}
} on Exception catch (err) {
playerModule.logger.e('error: $err');
}
setState(() {});
//playerModule.logger.d('<--seekToPlayer');
}
Widget makeDropdowns(BuildContext context) {
final mediaDropdown = Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Padding(
padding: EdgeInsets.only(right: 16.0),
child: Text('Media:'),
),
DropdownButton<Media>(
value: _media,
onChanged: (newMedia) {
_media = newMedia;
setState(() {});
},
items: const <DropdownMenuItem<Media>>[
DropdownMenuItem<Media>(
value: Media.file,
child: Text('File'),
),
DropdownMenuItem<Media>(
value: Media.buffer,
child: Text('Buffer'),
),
DropdownMenuItem<Media>(
value: Media.asset,
child: Text('Asset'),
),
DropdownMenuItem<Media>(
value: Media.remoteExampleFile,
child: Text('Remote Example File'),
),
DropdownMenuItem<Media>(
value: Media.stream,
child: Text('Dart Stream'),
),
],
),
],
);
final codecDropdown = Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Padding(
padding: EdgeInsets.only(right: 16.0),
child: Text('Codec:'),
),
DropdownButton<Codec>(
value: _codec,
onChanged: (newCodec) {
setCodec(newCodec!);
_codec = newCodec;
setState(() {});
},
items: const <DropdownMenuItem<Codec>>[
DropdownMenuItem<Codec>(
value: Codec.aacADTS,
child: Text('AAC/ADTS'),
),
DropdownMenuItem<Codec>(
value: Codec.opusOGG,
child: Text('Opus/OGG'),
),
DropdownMenuItem<Codec>(
value: Codec.opusCAF,
child: Text('Opus/CAF'),
),
DropdownMenuItem<Codec>(
value: Codec.mp3,
child: Text('MP3'),
),
DropdownMenuItem<Codec>(
value: Codec.vorbisOGG,
child: Text('Vorbis/OGG'),
),
DropdownMenuItem<Codec>(
value: Codec.pcm16,
child: Text('PCM16'),
),
DropdownMenuItem<Codec>(
value: Codec.pcm16WAV,
child: Text('PCM16/WAV'),
),
DropdownMenuItem<Codec>(
value: Codec.pcm16AIFF,
child: Text('PCM16/AIFF'),
),
DropdownMenuItem<Codec>(
value: Codec.pcm16CAF,
child: Text('PCM16/CAF'),
),
DropdownMenuItem<Codec>(
value: Codec.flac,
child: Text('FLAC'),
),
DropdownMenuItem<Codec>(
value: Codec.aacMP4,
child: Text('AAC/MP4'),
),
DropdownMenuItem<Codec>(
value: Codec.amrNB,
child: Text('AMR-NB'),
),
DropdownMenuItem<Codec>(
value: Codec.amrWB,
child: Text('AMR-WB '),
),
DropdownMenuItem<Codec>(
value: Codec.pcm8,
child: Text('PCM8 '),
),
DropdownMenuItem<Codec>(
value: Codec.pcmFloat32,
child: Text('PCM Float32 '),
),
DropdownMenuItem<Codec>(
value: Codec.pcmWebM,
child: Text('PCM/WebM '),
),
DropdownMenuItem<Codec>(
value: Codec.opusWebM,
child: Text('Opus/WebM '),
),
DropdownMenuItem<Codec>(
value: Codec.vorbisWebM,
child: Text('Vorbis/WebM '),
),
DropdownMenuItem<Codec>(
value: Codec.pcmFloat32WAV,
child: Text('PCM Float32/WAV'),
),
],
),
],
);
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: mediaDropdown,
),
codecDropdown,
],
),
);
}
void Function()? onPauseResumePlayerPressed() {
if (playerModule.isPaused || playerModule.isPlaying) {
return pauseResumePlayer;
}
return null;
}
void Function()? onPauseResumeRecorderPressed() {
if (recorderModule.isPaused || recorderModule.isRecording) {
return pauseResumeRecorder;
}
return null;
}
void Function()? onStopPlayerPressed() {
return (playerModule.isPlaying || playerModule.isPaused)
? stopPlayer
: null;
}
void Function()? onStartPlayerPressed() {
if (_media == Media.buffer && kIsWeb) {
return null;
}
if (_media == Media.file ||
_media == Media.stream ||
_media == Media.buffer) // A file must be already recorded to play it
{
if (_path[_codec.index] == null) return null;
}
if (_media == Media.stream && _codec != Codec.pcm16) {
return null;
}
// Disable the button if the selected codec is not supported
if (!(_decoderSupported ||
_codec == Codec.pcm16 ||
_codec == Codec.pcmFloat32)) {
return null;
}
return (playerModule.isStopped) ? startPlayer : null;
}
void startStopRecorder() {
if (recorderModule.isRecording || recorderModule.isPaused) {
stopRecorder();
} else {
startRecorder();
}
}
void Function()? onStartRecorderPressed() {
// Disable the button if the selected codec is not supported
if (!_encoderSupported!) return null;
if (_media == Media.stream && _codec != Codec.pcm16) return null;
return startStopRecorder;
}
AssetImage recorderAssetImage() {
if (onStartRecorderPressed() == null) {
return const AssetImage('res/icons/ic_mic_disabled.png');
}
return (recorderModule.isStopped)
? const AssetImage('res/icons/ic_mic.png')
: const AssetImage('res/icons/ic_stop.png');
}
Future<void> setCodec(Codec codec) async {
_encoderSupported = await recorderModule.isEncoderSupported(codec);
_decoderSupported = await playerModule.isDecoderSupported(codec);
setState(() {
_codec = codec;
});
}
@override
Widget build(BuildContext context) {
final dropdowns = makeDropdowns(context);
Widget recorderSection = Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 12.0, bottom: 16.0),
child: Text(
_recorderTxt,
style: const TextStyle(
fontSize: 35.0,
color: Colors.black,
),
),
),
_isRecording
? LinearProgressIndicator(
value: 100.0 / 160.0 * (_dbLevel ?? 1) / 100,
valueColor:
const AlwaysStoppedAnimation<Color>(Colors.indigo),
backgroundColor: Colors.limeAccent)
: Container(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
width: 56.0,
height: 50.0,
child: ClipOval(
child: TextButton(
onPressed: onStartRecorderPressed(),
//padding: EdgeInsets.all(8.0),
child: Image(
image: recorderAssetImage(),
),
),
),
),
SizedBox(
width: 56.0,
height: 50.0,
child: ClipOval(
child: TextButton(
onPressed: onPauseResumeRecorderPressed(),
//disabledColor: Colors.white,
//padding: EdgeInsets.all(8.0),
child: Image(
width: 36.0,
height: 36.0,
image: AssetImage(onPauseResumeRecorderPressed() != null
? 'res/icons/ic_pause.png'
: 'res/icons/ic_pause_disabled.png'),
),
),
),
),
],
),
]);
Widget playerSection = Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.only(top: 12.0, bottom: 16.0),
child: Text(
_playerTxt,
style: const TextStyle(
fontSize: 35.0,
color: Colors.black,
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
width: 56.0,
height: 50.0,
child: ClipOval(
child: TextButton(
onPressed: onStartPlayerPressed(),
//disabledColor: Colors.white,
//padding: EdgeInsets.all(8.0),
child: Image(
image: AssetImage(onStartPlayerPressed() != null
? 'res/icons/ic_play.png'
: 'res/icons/ic_play_disabled.png'),
),
),
),
),
SizedBox(
width: 56.0,
height: 50.0,
child: ClipOval(
child: TextButton(
onPressed: onPauseResumePlayerPressed(),
//disabledColor: Colors.white,
//padding: EdgeInsets.all(8.0),
child: Image(
width: 36.0,
height: 36.0,
image: AssetImage(onPauseResumePlayerPressed() != null
? 'res/icons/ic_pause.png'
: 'res/icons/ic_pause_disabled.png'),
),
),
),
),
SizedBox(
width: 56.0,
height: 50.0,
child: ClipOval(
child: TextButton(
onPressed: onStopPlayerPressed(),
//disabledColor: Colors.white,
//padding: EdgeInsets.all(8.0),
child: Image(
width: 28.0,
height: 28.0,
image: AssetImage(onStopPlayerPressed() != null
? 'res/icons/ic_stop.png'
: 'res/icons/ic_stop_disabled.png'),
),
),
),
),
],
),
SizedBox(
height: 30.0,
child: Slider(
value: min(sliderCurrentPosition, maxDuration),
min: 0.0,
max: maxDuration,
onChanged: (value) async {
await seekToPlayer(value.toInt());
},
divisions: maxDuration == 0.0 ? 1 : maxDuration.toInt())),
],
);
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Sound Demo'),
),
body: ListView(
children: <Widget>[
recorderSection,
playerSection,
dropdowns,
],
),
);
}
}
... ...