You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

921 lines
31 KiB
Dart

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import 'dart:async';
import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:io';
import 'dart:math';
import 'package:ai_save_account/ai_save_account.dart';
import 'package:audioplayers/audio_cache.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:camera/camera.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart' as crypto;
import 'package:device_info/device_info.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/provider/player_region.dart';
import 'UserInfo.dart';
import 'dioFun.dart';
////////////////////////////////////////////
AudioPlayer playerClick;
AudioPlayer playerClacks;
AudioPlayer playerVoiceRemind;
myPlayClick() async {
if (null == playerClick) {
print("myPlayClick first by load mp3 file");
playerClick = await AudioCache().play('audio/click.mp3');
} else {
print("myPlayClick resume() from cache");
playerClick.seek(Duration(milliseconds: 0));
playerClick.resume();
}
}
myPlayClacks() async {
if (null == playerClick) {
print("myPlayClick first by load mp3 file");
playerClick = await AudioCache().play('audio/clacks.mp3');
} else {
print("myPlayClick resume() from cache");
playerClick.seek(Duration(milliseconds: 0));
playerClick.resume();
}
}
myPlayVoiceRemind() async {
if (null == playerVoiceRemind) {
print("myPlayVoiceRemind first by load mp3 file");
playerVoiceRemind = await AudioCache().play('audio/语音提醒.mp3');
} else {
print("myPlayVoiceRemind resume() from cache");
playerVoiceRemind.seek(Duration(milliseconds: 0));
playerVoiceRemind.resume();
}
}
////////////////////////////////////////////
// begin hyzp_ybqx-Commit022-区县切换新方法-OK
// 1、修改手机桌面的App图标文本
// R:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\AndroidManifest.xml
// android:label="宜宾黑烟抓拍"
// android:label="宜宾市翠屏黑烟抓拍"
// android:label="宜宾三江新区黑烟抓拍"
// android:label="宜宾市长宁黑烟抓拍"
// android:label="宜宾市筠连黑烟抓拍"
// android:label="宜宾市兴文黑烟抓拍"
// 2、修改App的android和Flutter启动图片制作并运行 hyzp_ybqx.images_copy.cmd自动完成两项拷贝任务
// (1)、拷贝不同分辨率的图片文件hyzp_ybqx_launche.png到下面目录作为App的android启动图片
// r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-hdpi\
// r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-mdpi\
// r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-xhdpi\
// r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-xxhdpi\
// r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-xxxhdpi\
// (2)、拷贝 750 * 1334 的图片文件到下面目录作为App的Flutter启动图片
// r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\assets\images\hyzp_ybqx01_cuiping_launche.png
// 3、修改文本变量
// 位于文件 R:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\lib\components\commonFun.dart 中
// 511501、宜宾市
// String APPkey = 'ijddvzgEGaxbzsbmCtpdohxHyrAArwJB'; // 宜宾市APPkey
// String service_tel = '\n服务热线187-8467-8300';
// String yibin_QuXian = '宜宾';
// String copyright_info = '© ' + yibin_QuXian + '市生态环境局 四川省踏石科技有限公司 版权所有' + service_tel;
// String copyright_info_PinYin = 'YIBIN BLACK SMOKE CAR CAPTURE SYSTEM';
// const serviceUrl_ybqx = 'http://125.64.218.67:9904'; // 宜宾市
// const serviceUrl_ybqx_media = 'http://125.64.218.67:9908/'; // 宜宾市
// 区县APPkey
String APPkey = 'pdohxHyr79ddvzgE8ArwGaxb01bmCtJB';
// 区县后台地址
const serviceUrl_ybqx = 'http://125.64.218.67:9909';
// 区县违章图片和视频地址前缀
// const serviceUrl_ybqx_media = 'http://125.64.218.67:9912/';
// 20220320罗腾-子非鱼: @闵军 区县端口视频文件和图片文件的前缀,由原来的 http://125.64.218.67:9912/ 调整为 http://125.64.218.67:9906/
// 罗腾-子非鱼: 9912端口已被禁用
const serviceUrl_ybqx_media = 'http://125.64.218.67:9906/';
// 区县球机方向控制地址
// const String setSphericalCameraUrl = 'http://125.64.218.67:9914/'; //原来的
// 罗腾-子非鱼:因环保局缩减了我们的端口数量,现在对控制球机的接口进行调整。
// 1、控制端口由原来的 9914 调整为 9903
// 2、新增sip参数0表示市级平台1表示区县平台。之前是通过不同端口来分别访问市级和区县的因缩减了我们的端口数现在统一使用1个端口通过sip参数来区分市级和区县
const String setSphericalCameraUrl = 'http://125.64.218.67:9903/'; //新版的
const int g_sip = 1; // 新增sip参数0表示市级平台1表示区县平台。
///用于定时提醒的变量和函数
//获取待审核黑烟车记录
List listReviewed = [];
bool g_bVoiceRemind = false; // 用户设置是否开启语音提醒
int g_remindGap = 60; // 提醒间隔默认为60S0表示取消定时提醒
// Timer g_remindTimer; //定时提醒变量
//
// // 设置定时提醒
// setRemindTimer({bool enable = true}) {
// // 先取消旧的定时任务
// if (null != g_remindTimer) {
// g_remindTimer.cancel(); //取消计时器
// }
//
// // 设置新的定时任务
// if (enable && g_remindGap > 0) {
// ///循环执行定时任务,间隔 g_remindGap 秒
// g_remindTimer = Timer.periodic(Duration(seconds: g_remindGap), (timer) {
// ///定时任务
// doRemind();
// });
// }
// }
//
// // 执行语音提醒
// Future doRemind() async {
// // 获取待审核黑烟车记录
// if (g_bVoiceRemind) {
// listReviewed.clear();
// print("listReviewed = $listReviewed");
// await getReviewedList(); //注意:访问区县后台接口,需要统一添加区县代码参数
// print("listReviewed = $listReviewed");
// // if (g_bVoiceRemind) {
// // import 'dart:io';
// // import 'package:audioplayers/audio_cache.dart';
// // print("播放:语音提醒.mp3");
// if (listReviewed.length > 0) {
// // AudioCache().play(File('audio/语音提醒.mp3').path); //语音提醒
// myPlayVoiceRemind();
// }
// }
// }
///用于定时提醒的变量和函数
// {
// "ret": 200,
// "data": {
// "is_login": true,
// "user_id": 152,
// "token": "959091E2A5E362E22F22F8DBE05737A95545A43AF28B19AB3DAD5F8557EE2E29",
// "qx_code": "511528",
// "qx_name": "兴文县"
// },
// "msg": ""
// }
// 一套APP适应多个区县等用户登录后会返回 qx_code、qx_name
int qx_code = -1;
String qx_name = '';
String qx_name_long = '';
int qx_trial_tag = 0;
String service_tel = '';
String copyright_info = '';
String copyright_info_PinYin = '';
// 区县中心地址
double center_latitude = -1; // 区县中心纬度
double center_longitude = -1; // 区县中心经度
clear_user_info() {
qx_code = -1;
qx_name = '';
qx_name_long = '';
qx_trial_tag = 0;
service_tel = '';
copyright_info = '';
copyright_info_PinYin = '';
// 区县中心地址
center_latitude = -1; // 区县中心纬度
center_longitude = -1; // 区县中心经度
}
// 511528、兴文县
// int qx_code = 511528;
// String qx_name = '宜宾市兴文';
// String service_tel = '\n服务热线187-8467-8300';
// String copyright_info = '© ' + qx_name + '生态环境局 四川省踏石科技 版权所有' + service_tel;
// String copyright_info_PinYin = 'YIBIN XINGWEN BLACK SMOKE CAR CAPTURE SYSTEM';
// // 兴文县中心地址:天泉商城
// double center_latitude = 28.29678023715008; // 区县中心纬度
// double center_longitude = 105.24189826141459; // 区县中心经度
// 注意:百度官方发布的城市中心点坐标是经度在前、纬度在后,必须对调才行,否则无法正确显示指定城市的地图
// BMFCoordinate BMFCoordinate(double latitude (纬度), double longitude (经度)) //中国领域一般经度大些
// center: BMFCoordinate(28.77914, 104.644079), //宜宾市翠屏白塔山
// 在点位地图中点击某个标注,在控制台会显示该标注的纬度和经度
// 兴文县中心位置I/flutter (12538): mapPoi = {text: 半岛和居, pt: {latitude: 28.29678023715008, longitude: 105.24189826141459}, uid: b9e39ee2e8304f872fe67bcf}
// 兴文县5个点位坐标
// 序号 选址位置 车道数量 经纬度 用途
// 1 古高路骨科医院附近 双向6车道 105.19762 28.334613 抓拍自长宁、江安、珙县方向和古宜高速入城黑烟车辆
// 2 高铁站附近 双向4车道 105.239899 28.337284 抓拍自泸州纳溪区方向入城黑烟车辆
// 3 大礼村附近 双向2车道 105.270567 28.285734 抓拍自泸州叙永县方向入城黑烟车辆
// 4 石海收费站附近 双向4车道 105.251038 28.287758 抓拍自古宜高速入城黑烟车辆
// 5 温水溪加油站附近 双向2车道 105.246259 28.286645 抓拍自云南威信县方向入城黑烟车辆
// 4、全局替换将 ”hyzp_ybqx“全部替换为 ”hyzp_ybqx“自动完成以下修改
// (1)、修改 R:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\pubspec.yaml 文件中的AppID但存放目錄不變
// name: hyzp_ybqx
// (2)、全局替换:
// A、将 “com.flutter.hyzp_ybqx00_yibin” 全部替换为 “com.flutter.hyzp_ybqx”
// B、将 “package:hyzp_ybqx00_yibin/” 全部替换为 “package:hyzp_ybqx/”
// C、将 “# hyzp_ybqx00_yibin” 全部替换为 “# hyzp_ybqx”
// D、将 “<string>hyzp_ybqx00_yibin</string>” 全部替换为 “<string>hyzp_ybqx</string>”
// 5、完成以上修改后打开 Android Studio 的终端窗口,切换到项目的 lib 目录下,运行 flutter clean
// 6、重新编译运行App
// end hyzp_ybqx-Commit022-区县切换新方法-OK
////////////////////////////////////////////
//LED字幕信息
//String g_ledMessage = '绿水青山就是金山银山 宜宾市翠屏生态环境局宣。';
// 是否已经调用 FlutterDownloader.initialize(debug: true)
bool bFlutterDownloader_initialize = false;
bool bNewVer = false; //是否发现新版本
//处理延时登录,判断从网络获取三种统计数据是否完成
bool bMayLogin = true;
//处理延时登录,判断是否已经点击登录按钮
bool bPreLoading = false;
//处理延时登录,判断用户名登录是否验证通过
bool bLoginVerify = false;
bool bHasMore = true;
//part library
//dart中通过使用part、part of、library来实现拆分库这样就可以将一个庞大的库拆分成各种小库只要引用主库即可
//点位总数
int dwSum = -1;
Size sizeWindowPhysicalSize;
//String dateAppCompile = '2020.12.30'; //1.0.1+1
//String dateAppCompile = '2021.02.20'; //1.2.5+1
//String dateAppCompile = '2021.03.18'; //1.2.6+1
//String dateAppCompile = '2021.05.18'; //1.2.7
List<String> g_list = [];
//正在获取点位视频标志,禁止重入
bool getingDwVideo = false;
int getCount = 1; //获取点位视频地址尝试次数
int getSumTime = 0; //获取点位视频地址耗时(秒)
int getingIndex = -1; //正在获取视频的点位的索引号
String getingDwmc = ''; //正在获取视频的点位名称
String urlnew =
"http://www.yibinu.edu.cn/__local/5/35/DF/264049B7E978EEE2F5849688986_05D4A6FE_152CDB8C.mp4?e=.mp4";
bool isVideoUrl(String url, {bool showToast = false}) {
print('url = $url');
if (0 == url.length) {
return false;
}
String prefix = url.substring(0, 4);
List list = ['http', 'rtmp', 'rstp'];
for (String item in list) {
if (prefix == item) {
return true;
}
}
if (showToast) {
Fluttertoast.showToast(
msg: '获取视频地址失败',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
return false;
}
final TextEditingController myController = TextEditingController();
bool Playing = false; //禁止同时启动两次播放器
//final FijkPlayer player = FijkPlayer();
int g_iIndex = 0;
PlayerRegionProvide playerRegionProvide;
Future<void> sysPop() async {
// currentPos = player.currentPos.inMilliseconds; //seekto方法的参数是毫秒
// await writeCurrentPosFile();
// await player.stop();
await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}
//人脸注册和人脸识别登录成功标志
int faceReg = -1; //1 成功0 失败,-1 处理中
int faceLogin = -1; //1 成功0 失败,-1 处理中
//人脸注册时所需用户ID
int faceRegUserID = -1; //人脸注册时所需用户ID-1 非法
List<CameraDescription> cameras;
List<UserAccount> g_users = new List(); //历史账号
bool g_can_expand_ListView = false; //是否能够打开历史账号
UserInfo g_userInfo = UserInfo(mapUserInfoRet: {
"ret": 200,
"data": {
"is_login": true,
"user_id": 152,
"token": "959091E2A5E362E22F22F8DBE05737A95545A43AF28B19AB3DAD5F8557EE2E29",
"qx_code": "511528",
"qx_name": "兴文县",
"sfsy": 0, //区县用户登录接口增加返回字段“sfsy”0表示正式账号1表示试用账号
},
"msg": ""
});
// 去除末尾的区县
String trim_county(String _name) {
return _name.substring(0, _name.length - 1);
}
Future<Map> getMapFromJson(var response) async {
String _str = json.encode(response);
Map _map = json.decode(_str);
return _map;
}
// Future<void> getVideoList(BuildContext context) async {
// List<AssetEntity> assets = <AssetEntity>[];
// return await MyAssetPicker.pickAssets(
// context,
// maxAssets: 1,
// selectedAssets: assets,
// requestType: RequestType.video,
// );
// }
Future<String> getAndroidId() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
//print('每个手机唯一的设备号:${androidInfo.androidId}'); // e.g. "Moto G (4)"
g_userInfo.thisAndroidId = androidInfo.androidId;
return g_userInfo.thisAndroidId;
}
// void playOrPause() {
// playerRegionProvide.changePlayerState(bPlaying);
//
// if (bPlaying) {
// player.start();
// } else {
// player.pause();
// }
//
// Storage.setString('bFirstPlay', bFirstPlay ? 'true' : 'false');
// Storage.setString('bPlaying', bPlaying ? 'true' : 'false');
//
// //updateFile();
// }
//
// void playAndPause() {
// if (player.state == FijkState.started) {
// bPlaying = false;
// player.pause();
// } else if (player.state == FijkState.paused) {
// bPlaying = true;
// player.start();
// }
// //setState(() {});
// playerRegionProvide.changePlayerState(bPlaying);
// Storage.setString('bPlaying', bPlaying ? 'true' : 'false');
// }
Alignment getAlignment(Offset offset, Size size) {
// final double centerX = offset.dx / 2.0;
// final double centerY = offset.dy / 2.0;
//offset.dx = centerX + alignment.x * centerX;
//double alignmentX = (0.0 == centerX) ? 0.0 : ((offset.dx - centerX) / centerX);
double alignmentX = (offset.dx / size.width).clamp(-1.0, 1.0);
//offset.dy = centerY + alignment.y * centerY;
//double alignmentY = (0.0 == centerY) ? 0.0 : ((offset.dy - centerY) / centerY);
double alignmentY = (offset.dy / size.height).clamp(-1.0, 1.0);
// print('offset.dx = ${offset.dx}, offset.dy = ${offset.dy}');
print('Alignment.X = $alignmentX, Alignment.Y = $alignmentY');
return Alignment(alignmentX, alignmentY);
}
//flutter dart生成N位随机数
//https://blog.csdn.net/qq_36071410/article/details/101268640
// 庄童 2019-09-24 10:24:58 10271 收藏
String RandomBit(int len) {
String scopeF = '123456789'; //首位
String scopeC = '0123456789'; //中间
String result = '';
for (int i = 0; i < len; i++) {
if (i == 0) {
result = scopeF[Random().nextInt(scopeF.length)];
} else {
result = result + scopeC[Random().nextInt(scopeC.length)];
}
}
return result;
}
// sign=md5(ijddvzgEGaxbzsbmCtpdohxHyrAArwJB1003)
// =3967eaebec0eed0642a1d395ac9293dd
// String APPkey = 'ijddvzgEGaxbzsbmCtpdohxHyrAArwJB'; // 宜宾APPkey
//Flutter对字符串进行MD5运算 发表于 2019-03-26 更新于 2020-12-04 分类于 Flutter 阅读次
String GenerateMd5(String str) {
var content = new Utf8Encoder().convert(str);
var md5 = crypto.md5;
var digest = md5.convert(content);
return hex.encode(digest.bytes);
}
//加载中的圈圈
Widget getMoreWidget2({
Color color = Colors.white,
String text = '加载中...',
double size = 30.0,
double strokeWidth = 3.0,
FontWeight fontWeight,
double edge = 10.0,
double height = 34,
}) {
return Center(
child: Padding(
padding: EdgeInsets.all(edge),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: size,
width: size,
child: CircularProgressIndicator(
strokeWidth: strokeWidth,
valueColor: AlwaysStoppedAnimation<Color>(color),
),
),
SizedBox(
height: ScreenUtil().setHeight(height),
),
Text(
text,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: size, // 文字大小
color: color,
fontWeight: fontWeight, // 文字颜色
),
),
],
),
),
);
}
//加载中的圈圈
Widget getMoreWidget({
String text = '加载中...',
Color color = Colors.white,
double size = 30.0,
double strokeWidth = 3.0,
TextAlign textAlign = TextAlign.left,
}) {
return Center(
child: Padding(
padding: EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: size,
width: size,
child: CircularProgressIndicator(
strokeWidth: strokeWidth,
valueColor: AlwaysStoppedAnimation<Color>(color),
),
),
SizedBox(
height: 10,
),
Text(
text,
textAlign: textAlign,
style: TextStyle(
fontSize: size, // 文字大小
color: color,
),
),
],
),
),
);
}
//自定义带说明图标按钮函数。点击说明文字有反应
Widget getIconAndTextButton(
{IconData iconData, Color iconColor = Colors.black, var onPress = null}) {
return Container(
width: 50,
height: 50,
alignment: const Alignment(0, 0),
child: FlatButton(
padding: EdgeInsets.all(0),
onPressed: onPress,
//color: Colors.blue,
color: Colors.transparent,
//解决报错问题FittedBox ← Expanded ← ConstrainedBox ← Container ← Center ← Padding ←
// Container ← IconTheme ← Builder ← _PointerListener
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 36, //最大高度
maxWidth: 36, //最大宽度
),
child: Padding(
padding: EdgeInsets.only(top: 1),
child: Icon(iconData, color: iconColor, size: 32),
// child: Image.asset(
// 'assets/images/left_arrow.png',
// fit: BoxFit.fitWidth,
// color: iconColor,
// //fit: BoxFit.cover,
// ),
),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Image.asset('assets/images/left_arrow.png', fit: BoxFit.cover),
// // Expanded(
// // //child: Icon(iconData, color: iconColor, size: 24),
// // child: Image.asset('assets/images/left_arrow.png', fit: BoxFit.cover),
// // ),
// ],
// ),
),
//The offending Expanded is currently placed inside a ConstrainedBox widget.
//The ownership chain for the RenderObject that received the incompatible parent data was:
// FittedBox ← Expanded ← ConstrainedBox ← Container ← Center ← Padding ← Container ← IconTheme ←
//Builder ← _PointerListener
//The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a
//RenderObject, which has been set up to accept ParentData of incompatible type ParentData.
//Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically,
//Expanded widgets are placed directly inside Flex widgets.
//The offending Expanded is currently placed inside a FittedBox widget.
//The ownership chain for the RenderObject that received the incompatible parent data was:
// ConstrainedBox ← Container ← Expanded ← FittedBox ← Center ← Padding ← Container ← IconTheme ←
//Builder ← _PointerListener ← ⋯
// child: ConstrainedBox(
// constraints: BoxConstraints(
// maxHeight: 20, //最大高度
// maxWidth: 28, //最大宽度
// ),
// child: Container(
// child: Expanded(
// child: new Icon(iconData, color: iconColor),
// ),
// ),
// ),
// child: ConstrainedBox(
// constraints: BoxConstraints(
// maxHeight: 30, //最大高度
// maxWidth: 38, //最大宽度
// minWidth: 38, //最大宽度
// ),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Expanded(
// child: Icon(iconData, color: iconColor, size: 24),
// ),
// ],
// ),
// ),
// child: Container(
// width: 28,
// height: 20,
// child: Expanded(
// child: new FittedBox(
// fit: BoxFit.fill,
// child: new Icon(iconData, color: iconColor),
// ),
// ),
// ),
// child: FittedBox(
// fit: BoxFit.fitWidth,
// alignment: Alignment.topLeft,
// child: Container(
// width: 28,
// height: 20,
// child: Expanded(
// child: new FittedBox(
// fit: BoxFit.fill,
// child: new Icon(iconData, color: iconColor),
// ),
// ),
// ),
// ),
),
);
}
///获取缩进空白符
String getDeepSpace(int deep) {
var tab = StringBuffer();
for (int i = 0; i < deep; i++) {
tab.write("\t");
}
return tab.toString();
}
// List map2list(Map _map) {
// List _list = [];
// _list = List.generate(listContacts2[widget.contactIndex].length, (index) {
// String key = listContacts2[widget.contactIndex].keys.elementAt(index);
// //return TextEditingController(text: listContacts2[widget.contactIndex][key]);
// return TextEditingController(text: getUserText3(widget.contactIndex, key));
// });
//
// }
/// [object] 解析的对象
/// [deep] 递归的深度,用来获取缩进的空白长度
/// [isObject] 用来区分当前map或list是不是来自某个字段则不用显示缩进。单纯的map或list需要添加缩进
String json_print(dynamic object, int deep, {bool isObject = false}) {
var buffer = StringBuffer();
var nextDeep = deep + 1;
if (object is Map) {
var list = object.keys.toList();
if (!isObject) {
//如果map来自某个字段则不需要显示缩进
buffer.write("${getDeepSpace(deep)}");
}
buffer.write("{");
if (list.isEmpty) {
//当map为空直接返回}
buffer.write("}");
} else {
buffer.write("\n");
for (int i = 0; i < list.length; i++) {
buffer.write("${getDeepSpace(nextDeep)}\"${list[i]}\":");
buffer.write(json_print(object[list[i]], nextDeep, isObject: true));
if (i < list.length - 1) {
buffer.write(",");
buffer.write("\n");
}
}
buffer.write("\n");
buffer.write("${getDeepSpace(deep)}}");
}
} else if (object is List) {
if (!isObject) {
//如果list来自某个字段则不需要显示缩进
buffer.write("${getDeepSpace(deep)}");
}
buffer.write("[");
if (object.isEmpty) {
//当list为空直接返回]
buffer.write("]");
} else {
buffer.write("\n");
for (int i = 0; i < object.length; i++) {
buffer.write(json_print(object[i], nextDeep));
if (i < object.length - 1) {
buffer.write(",");
buffer.write("\n");
}
}
buffer.write("\n");
buffer.write("${getDeepSpace(deep)}]");
}
} else if (object is String) {
//为字符串时,需要添加双引号并返回当前内容
buffer.write("\"$object\"");
} else if (object is num || object is bool) {
//为数字或者布尔值时,返回当前内容
buffer.write(object);
} else {
//如果对象为空则返回null字符串
buffer.write("null");
}
return buffer.toString();
}
//人脸识别和上传的图片,都需要转换为 Base64 格式的字符串提交
//通过图片路径将图片转换成 Base64 字符串
Future image2Base64(String imagePath) async {
File file = File(imagePath);
List<int> imageBytes = await file.readAsBytes();
String bs64 = base64Encode(imageBytes);
String ext = getFileExtension(imagePath);
print('imagePath = $imagePath, ext = $ext');
//String bs64Image = "data:image/png;base64," + bs64;
String bs64Image = "data:image/${ext};base64," + bs64;
return bs64Image;
}
//从字符路径 path 获取扩展名,不含点号
getFileExtension(String path) {
//return path.substring(path.lastIndexOf('.'));
//imagePath = /data/user/0/com.flutter.hyzp_ybqx/app_flutter/Pictures/flutter_test/1614662209478.jpg, ext = .jpg
return path.substring(path.lastIndexOf('.') + 1); //不含点号
}
//从字符路径 path 获取文件名(含扩展名)
getFileName(String path) {
//return path.substring(path.lastIndexOf('.'));
//imagePath = /data/user/0/com.flutter.hyzp_ybqx/app_flutter/Pictures/flutter_test/1614662209478.jpg, ext = .jpg
return path.substring(path.lastIndexOf('/') + 1); //不含点号
}
Widget getBtnSizeX({@required text, double width = 70.0, double height = 40.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
//返回主页ashamp
// 博客园首页新随笔联系管理订阅订阅随笔 - 33 文章 - 0 评论 - 51 阅读 - 55018
// 在debug时使Flutter中的print打印json数据时更美观易读
// 为了避免deubg信息在生产环境打印,只在测试时打印,在main函数中,改变debugPrint的指向
//
// 复制代码
// main(){
// if (Api.isDebug) {
// debugPrint = (String message, {int wrapWidth}) {
// try {
// var object = json.decode(message);
// message = JsonEncoder.withIndent(' ').convert(object);
// } catch (e) {}
// printWrapped(message);
// };
// } else {
// debugPrint = (String message, {int wrapWidth}) {};
// }
// }
// 复制代码
// 将printWrapped方法放入工具类或你需要的地方
//
// void printWrapped(String text) {
// final pattern = new RegExp('.{1,800}'); // 800 is the size of each chunk
// pattern.allMatches(text).forEach((match) => developer.log(match.group(0)));
// }
// log方法需要引入
//
// import 'dart:developer' as developer;
//
//在debug时使 Flutter 中的 print 打印 json 数据时更美观易读
void jsonPrint(String message, {int len = 800}) {
//是否在生产环境
const bool isDebug = !const bool.fromEnvironment("dart.vm.product");
// if (!isDebug) {
// return;
// }
try {
var object = json.decode(message);
message = JsonEncoder.withIndent(' ').convert(object);
} catch (e) {
print('e = $e');
}
printWrapped(message);
}
// 打印长字符串
void printWrapped(String text, {int len = 800}) {
final pattern = RegExp('.{1,$len}'); // 800 is the size of each chunk
pattern.allMatches(text).forEach((match) => developer.log(match.group(0)));
}
//OK
void my_segmentPrint(String str, {int len = 800}) {
//是否在生产环境
const bool isDebug = !const bool.fromEnvironment("dart.vm.product");
if (!isDebug) {
return;
}
List list = strToList(str);
for (int i = 0; i < list.length; i++) {
print('${list[i]}');
}
}
//OK
List strToList(String str, {int len = 800}) {
List<String> strList = [];
if (str.length <= len) {
strList.add(str);
} else {
int splitCount = str.length ~/ len; //应该切割的次数
for (int i = 0; i < splitCount; i++) {
strList.add(str.substring(len * i, len * (i + 1)));
}
//处理最后一段
if (str.length % len != 0) {
strList.add(str.substring(len * splitCount));
}
}
print('strList:${strList.toString}');
return strList;
}
Widget getImageWidget() {
return Container(
alignment: Alignment(0, 0),
height: ScreenUtil().setHeight(346),
width: ScreenUtil().setWidth(942),
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage('assets/images/装饰图片10.png'), fit: BoxFit.cover),
),
child: Column(
children: [
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(top: ScreenUtil().setWidth(30), left: ScreenUtil().setWidth(55)),
child: Text('改善城市空气质量', style: TextStyle(fontSize: 17, color: Colors.white)),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: ScreenUtil().setWidth(55)),
child: Text('建设长江生态第一城',
style: TextStyle(
fontSize: 19,
color: Color.fromRGBO(49, 216, 123, 1),
fontWeight: FontWeight.bold)),
),
SizedBox(height: ScreenUtil().setHeight(copyright_info.contains('\n') ? 50 : 90)),
Container(
alignment: Alignment.center,
child: Text(copyright_info,
style: TextStyle(fontSize: 13, color: Color.fromRGBO(192, 192, 192, 1)),
textAlign: TextAlign.center),
),
],
),
// child: Image.asset(
// 'assets/images/装饰图片10.png',
// fit: BoxFit.cover,
// ),
);
}
Widget getIconBtnSizeX(
{@required text,
width = 233,
height = 116,
onTop,
Color color = Colors.black,
double circular = 10,
double textSize = 18}) {
return InkWell(
onTap: onTop,
child: Container(
alignment: Alignment(0, 0),
margin: EdgeInsets.all(0),
padding: EdgeInsets.all(0),
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height),
decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(circular)),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: ScreenUtil().setWidth(12)),
Icon(Icons.play_arrow, color: Colors.white, size: ScreenUtil().setWidth(56)),
Text(
text,
style: TextStyle(color: Colors.white, fontSize: textSize),
)
],
),
),
);
}