import 'dart:async'; import 'dart:io'; import 'package:amap_location_flutter_plugin/amap_location_flutter_plugin.dart'; import 'package:amap_location_flutter_plugin/amap_location_option.dart'; import 'package:flutter/material.dart'; import 'package:liftmanager/net/api_service.dart'; import 'package:liftmanager/utils/toast.dart'; import 'package:liftmanager/widgets/app_bar.dart'; import 'package:liftmanager/routers/fluro_navigator.dart'; import 'package:liftmanager/widgets/selected_video_change.dart'; import 'package:image_picker/image_picker.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:liftmanager/internal/wode/wode_router.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:liftmanager/utils/theme_utils.dart'; import 'package:liftmanager/utils/url.dart'; import 'package:liftmanager/utils/utils.dart'; import 'package:video_player/video_player.dart'; import 'package:chewie/chewie.dart'; import 'package:flutter/services.dart'; import 'package:orientation/orientation.dart'; import 'package:liftmanager/utils/fast_notification.dart'; import 'package:liftmanager/utils/oss_upload.dart'; class Punchin extends StatefulWidget { Punchin(this.id); final String id; @override State createState() { return PunchinState(); } } class PunchinState extends State { String videoUrl; String str; String imagesUrl; double percent = 0.0; Map _locationResult; StreamSubscription> _locationListener; AmapLocationFlutterPlugin _locationPlugin = new AmapLocationFlutterPlugin(); var latitude; var longitude; String address; @override void initState() { super.initState(); ///移除定位监听 if (null != _locationListener) { _locationListener.cancel(); } ///销毁定位 if (null != _locationPlugin) { _locationPlugin.destroy(); } _locationListener = _locationPlugin .onLocationChanged() .listen((Map result) { setState(() { _locationPlugin.stopLocation(); _locationResult = result; // address latitude longitude latitude = _locationResult["latitude"]; longitude = _locationResult["longitude"]; address = _locationResult["address"]; }); }); initGetLocation(); } void _setLocationOption() { if (null != _locationPlugin) { AMapLocationOption locationOption = new AMapLocationOption(); ///是否单次定位 locationOption.onceLocation = true; ///是否需要返回逆地理信息 locationOption.needAddress = true; ///逆地理信息的语言类型 locationOption.geoLanguage = GeoLanguage.DEFAULT; ///设置Android端连续定位的定位间隔 locationOption.locationInterval = 20000; ///设置Android端的定位模式
///可选值:
///
  • [AMapLocationMode.Battery_Saving]
  • ///
  • [AMapLocationMode.Device_Sensors]
  • ///
  • [AMapLocationMode.Hight_Accuracy]
  • locationOption.locationMode = AMapLocationMode.Hight_Accuracy; ///设置iOS端的定位最小更新距离
    locationOption.distanceFilter = -1; ///设置iOS端期望的定位精度 /// 可选值:
    ///
  • [DesiredAccuracy.Best] 最高精度
  • ///
  • [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度
  • ///
  • [DesiredAccuracy.NearestTenMeters] 10米
  • ///
  • [DesiredAccuracy.Kilometer] 1000米
  • ///
  • [DesiredAccuracy.ThreeKilometers] 3000米
  • locationOption.desiredAccuracy = DesiredAccuracy.NearestTenMeters; ///设置iOS端是否允许系统暂停定位 locationOption.pausesLocationUpdatesAutomatically = false; ///将定位参数设置给定位插件 _locationPlugin.setLocationOption(locationOption); } } VideoPlayerController _controller; VideoPlayerController _controllerFile; ///选择图片 void selectPicker() { showDialog( context: context, builder: (BuildContext context) { return SimpleDialog( title: Text("选择方式"), children: ["拍照", '从手机相册选择'].map((String value) { print("$value"); return SimpleDialogOption( child: Text( "${value}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), onPressed: () { _getImage(value == '拍照' ? 1 : 0); Navigator.of(context).pop(); }, ); }).toList(), ); }, ); } void _getImage(int key) async { print(key); print(333); try { await ImagePicker.pickVideo( source: key == 1 ? ImageSource.camera : ImageSource.gallery, ) .then((File f) async{ if (f != null) { _controllerFile = VideoPlayerController.file(f); _controllerFile.initialize().then((val){ _controllerFile.setLooping(true); int seconds = _controllerFile.value.duration.inSeconds; print("视频时长:$seconds"); int fileSize=f.lengthSync();//单位B print("视频大小:${fileSize}"); print("视频大小:${f.path}"); if (seconds <= 300) { _uploadImage(f.path); // upLoadFileOnce(_imageFile.path); // setState(() {}); }else { toasts("视频时长不能大于5分钟!"); } });} }) ; } catch (e) { toasts("没有权限,无法打开相册!"); } } upLoadFileOnce(path) { showLoading(context, "正在上传..."); NewApiService().upload(path, onSuccess: (res) { dismissLoading(context); setState(() { videoUrl = res.pathUrl; imagesUrl = res.coverUrl; }); }, onError: (code, msg) { dismissLoading(context); toasts(msg); }); } void _uploadImage(filePath) async { showPercent(context, (){ dismissLoading(context); toasts("上传失败"); },(){ if(videoUrl == null && str != null){ setState(() { videoUrl = str; print("videoUrl:"+videoUrl); dismissLoading(context); toasts("上传成功"); }); } }); String uploadName = OssUtil.instance.getImageUploadName(filePath); await NewApiService.uploadImage(context, uploadName, filePath).then((data) { if (data.statusCode == 200) { str = NewApiUrl.URL_UPLOAD_IMAGE_OSS + "/" + uploadName; print("str:"+str); print(videoUrl); if(str != null){ Map obj = { "uploadName":uploadName, "success":true }; FastNotification.push("percent",obj); } }else { Map obj = { "uploadName":uploadName, "success":false }; FastNotification.push("percent",obj); } }).catchError((data) { Map obj = { "uploadName":uploadName, "success":false }; FastNotification.push("percent",obj); }); } // 获取位置信息 initGetLocation() async { if (await requestPermission()) { if (null != _locationPlugin) { ///开始定位之前设置定位参数 _setLocationOption(); _locationPlugin.startLocation(); } } } // 获取定位权限 Future requestPermission() async { final permissions = await PermissionHandler() .requestPermissions([PermissionGroup.location]); if (permissions[PermissionGroup.location] == PermissionStatus.granted) { return true; } else { toasts('需要定位权限!'); return false; } } // 获取位置信息 Future getLocation() async { if (await requestPermission()) { if (null != _locationPlugin) { ///开始定位之前设置定位参数 _setLocationOption(); _locationPlugin.startLocation(); if(longitude!=null && latitude!=null){ if (videoUrl == null || videoUrl == '') { toasts("请上传视频"); return; } showLoading(context); NewApiService().chargeToClock({ "id": widget.id, "lng": longitude, "lat": latitude, "beforeRepair": videoUrl, }, onSuccess: (res) { dismissLoading(context); toasts("确认打卡成功"); NavigatorUtils.push(context, "${WodeRouter.orderPageMaster}?checkType=0"); setState(() {}); }, onError: (code, msg) { dismissLoading(context); toasts(msg); }); } } } } submitApply() { getLocation(); } // 文本编辑控制 GlobalKey _formKey = new GlobalKey(); @override void dispose() { _controller.pause(); _controller.dispose(); ///移除定位监听 if (null != _locationListener) { _locationListener.cancel(); } ///销毁定位 if (null != _locationPlugin) { _locationPlugin.destroy(); } // SystemChrome.setPreferredOrientations([ // DeviceOrientation.portraitUp, // ]); OrientationPlugin.forceOrientation(DeviceOrientation.portraitUp); super.dispose(); } @override Widget build(BuildContext context) { double width = MediaQuery.of(context).size.width; double height = MediaQuery.of(context).size.height; if(width > height){ // SystemChrome.setPreferredOrientations([ // DeviceOrientation.portraitUp, // ]); OrientationPlugin.forceOrientation(DeviceOrientation.portraitUp); } return Scaffold( resizeToAvoidBottomPadding: false, //不让键盘弹上去 appBar: MyAppBar( centerTitle: "打卡", ), body: Container( child: ListView( children: [ Form( key: _formKey, //设置globalKey,用于后面获取FormState // autovalidate: true, //开启自动校验 child: Column( children: [ Container( width: width, padding: EdgeInsets.only(left:15,top:15,bottom:15), child: Text( "(建议时长3分钟,建议大小50M)", style: TextStyle( color: Colors.red, fontSize: ScreenUtil() .setSp(14), ), textAlign: TextAlign.left, ), ), Container( color: ThemeUtils.getDialogTextFieldColor(context), child: GridView.builder( shrinkWrap: true, padding: const EdgeInsets.fromLTRB(8.0, 12, 8.0, 12.0), physics: NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 1, childAspectRatio: 1.18), itemCount: 1, itemBuilder: (_, index) { return Stack( children: [ Center( child: SelectedVideo( image: videoUrl, index: index, videoPlay:videoPlay(), onTap: () { if(videoUrl == null){ selectPicker(); } }, ), ), videoUrl != null ? Positioned( top: 0, right: 0, child: GestureDetector( onTap: () { setState(() { videoUrl = null; str = null; _controller.pause(); // player.reset(); }); }, child: Icon( IconData(0xe62a, fontFamily: "myfont"), size: 24.0, color: Color(0xff999999), ), ), ) : Container( child: null, ) ], ); }, ), ), Container( width: width, padding: EdgeInsets.all(15), child: Text( "当前打卡位置:"+ (address??""), textAlign: TextAlign.start, ), ), Container( height: ScreenUtil().setWidth(44), decoration: BoxDecoration( borderRadius: BorderRadius.circular(ScreenUtil().setWidth(22)), gradient: const LinearGradient( colors: [Color(0xFF00D9FF), Color(0xFF0287FF)]), ), margin: EdgeInsets.all(20.0), width: double.infinity, child: FlatButton( // padding: EdgeInsets.all(15.0), child: Text("提交"), // color: Theme // .of(context) // .primaryColor, textColor: Colors.white, onPressed: () { /* * 如果:context不对。可以使用GlobalKey, * 通过_formKey.currentState 获取FormState后, * 调用validate()方法校验用户名密码是否合法,校验 * 通过后再提交数据。 */ if ((_formKey.currentState as FormState).validate()) { submitApply(); } }, ), ), ], ), ), ], ), ), ); } Widget videoPlay() { _controller = VideoPlayerController.network( Utils.getImagePath(videoUrl) // imgFontUrl + detailObj.url ); double width = MediaQuery.of(context).size.width; return Container( width: width, height: width*2/3, padding: EdgeInsets.only( left: ScreenUtil().setWidth(15), right: ScreenUtil().setWidth(15), top: ScreenUtil().setWidth(15)), child: ClipRRect( borderRadius: BorderRadius.circular(5), child: new Chewie( controller: ChewieController( videoPlayerController: // VideoPlayerController.network( // imgFontUrl + detailObj.url // ), _controller, aspectRatio: 3 / 2, autoPlay: false, looping: true, showControls: true, deviceOrientationsAfterFullScreen:[DeviceOrientation.portraitUp,], // 占位图 // placeholder: Image.network( // imgFontUrl+detailObj.cover, // fit: BoxFit.contain, // ), // 是否在 UI 构建的时候就加载视频 autoInitialize: true, // 拖动条样式颜色 materialProgressColors: new ChewieProgressColors( playedColor: Colors.red, handleColor: Colors.blue, backgroundColor: Colors.grey, bufferedColor: Colors.lightGreen, ), ), ), )); } }