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: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 '../my_wechat_assets_picker_fix/my_asset_picker_1.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/provider/player_region.dart';

import 'UserInfo.dart';

////////////////////////////////////////////
// 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表示区县平台。
bool g_bVoiceRemind = false;  // 用户设置是否开启语音提醒

// {
//     "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> getDeviceId() async {
  DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
  if (Platform.isAndroid) {
    AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
    return androidInfo.androidId;
  } else if (Platform.isIOS) {
    return (await deviceInfo.iosInfo).identifierForVendor;
  }
  assert(false, 'Unsupported Platform');
  return '';
}

// 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),
          )
        ],
      ),
    ),
  );
}
