import 'dart:io'; import 'package:flutter/material.dart'; import 'package:health_kit_reporter/health_kit_reporter.dart'; import 'package:health_kit_reporter/model/type/quantity_type.dart'; import 'package:health_kit_reporter/model/type/workout_type.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:sport/pages/home/step_realtime_page.dart'; import 'package:sport/pages/run/run_start.dart'; import 'package:sport/pages/run/setting_healthkit_page.dart'; import 'package:sport/pages/run/setting_permission_page.dart'; import 'package:sport/provider/user_model.dart'; import 'package:sport/router/navigator_util.dart'; import 'package:sport/utils/toast.dart'; import 'package:sport/widgets/button_primary.dart'; import 'package:sport/widgets/dialog/alert_dialog.dart'; connectHealthKit() async { try { final readTypes = [ QuantityType.stepCount.identifier, QuantityType.distanceWalkingRunning.identifier, ]; final writeTypes = [ QuantityType.activeEnergyBurned.identifier, QuantityType.distanceWalkingRunning.identifier, WorkoutType.workoutType.identifier, ]; final isRequested = await HealthKitReporter.requestAuthorization(readTypes, writeTypes); if (isRequested) {} } catch (e) { print(e); } } Future requestBackground(BuildContext context) async { var preferences = await SharedPreferences.getInstance(); bool _background = preferences.getBool("RUN_BACKGROUND") ?? false; if (!_background) { var result = await showDialog( context: context, builder: (context) => CustomAlertDialog( title: "提示", child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Text( "由于您当前的操作系统版本会管控后台设置,可能会在运动记录过程中误杀趣动进程,为避免运动记录异常、距离不准确、轨迹点漂移等问题,建议您将趣动后台配置更改为【无限制】,以便我们能为您更准确地记录运动数据", style: TextStyle(fontSize: 16.0, color: Color(0xff333333), height: 1.8), ), ), textCancel: "稍后", textOk: "立即设置", ok: () { Navigator.pop(context, true); }, )); if (result == true) { preferences.setBool("RUN_BACKGROUND", true); if (!await jumpBackgroundPermission()) { await NavigatorUtil.goPage(context, (context) => SettingPermissionPage()); } _background = true; } } return _background; // bool checkPermissions = await SystemAlertWindow.checkPermissions; // if (!checkPermissions) { // var result = await showDialog( // context: context, // builder: (context) => CustomAlertDialog( // title: "提示", // child: Padding( // padding: const EdgeInsets.symmetric(horizontal: 20.0), // child: Text( // "由于您当前的操作系统版本会管控后台设置,可能会在运动记录过程中误杀趣动进程,请您开启悬浮窗权限以保证正常运动。", // style: TextStyle(fontSize: 16.0, color: Color(0xff333333)), // ), // ), // textCancel: "稍后", // textOk: "立即设置", // ok: () { // Navigator.pop(context, true); // }, // )); // if (result == true) { // await SystemAlertWindow.requestPermissions; // } // return false; // } // return true; } Future runCheck(BuildContext context) async { PermissionStatus status = await Permission.locationWhenInUse.request(); if (status.isGranted != true) { ToastUtil.show("请授权位置信息后使用该功能!"); openAppSettings(); return false; } var preferences = await SharedPreferences.getInstance(); if (Platform.isAndroid) { //1111 status PermissionStatus.denied false PermissionStatus.granted false false // 1111 status false if ((await Permission.locationAlways.status).isGranted != true) { if ((preferences.getBool("locationAlways_isPermanentlyDenied") ?? false) != true) { var result = await showDialog( context: context, builder: (context) => CustomAlertDialog( title: "地理位置权限申请", child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Text( "运动中的轨迹记录相关功能需要您授权地理位置权限。建议开户【始终允许】地理位置权限,否则锁屏后可能无法记录位置。", style: TextStyle(fontSize: 16.0, color: Color(0xff333333), height: 1.8), ), ), textOk: "立即设置", cancelable: false, ok: () { Navigator.pop(context, true); }, )); if (result) { PermissionStatus status = await Permission.locationAlways.request(); if (status.isGranted == true) { } else if (status.isPermanentlyDenied == true) { preferences.setBool("locationAlways_isPermanentlyDenied", true); } else { ToastUtil.show("请授权位置信息【始终允许】后再尝试"); return false; } } else { return false; } } } await Permission.activityRecognition.request(); await requestBackground(context); } else if (Platform.isIOS) { await Permission.sensors.request(); if (!preferences.containsKey("HEALTH_KIT")) { await NavigatorUtil.goPage(context, (context) => SettingHealthKitPage()); preferences.setBool("HEALTH_KIT", true); } } return true; } Future startRun(BuildContext context) async { bool result = await runCheck(context); if (result == true) await NavigatorUtil.goPage(context, (context) => RunStartPage()); // await NavigatorUtil.goPage(context, (context) => RunPage()); // // var package = "com.ouj.hiyd"; // var componentName = "com.ouj.hiyd.SplashActivity_"; // // if (Platform.isAndroid) { // var sport = await app.DeviceApps.getApp(package); // if (sport == null) { // ToastUtil.show("你还没安装 Hi运动 app"); // return; // } // AndroidIntent intent = AndroidIntent( // action: "android.intent.action.MAIN", // package: package, // componentName: componentName, // flags: [Flag.FLAG_ACTIVITY_NEW_TASK], // arguments: {}); // intent.launch(); // } } class GameRun extends StatelessWidget { @override Widget build(BuildContext context) { return Row( children: [ Container( width: 50.0, height: 50.0, margin: const EdgeInsets.all(12.0), child: Image.asset("lib/assets/img/home_game_run.png"), // child: Image.asset("lib/assets/img/game_icon_function.png") ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "跑步训练", style: Theme.of(context).textTheme.subtitle1!.copyWith(fontSize: 16.0, fontWeight: FontWeight.w600), ), SizedBox( height: 3, ), ValueListenableBuilder( valueListenable: Provider.of(context, listen: false).runUserCount, builder: (BuildContext context, int value, Widget? child) => Text("$value人在练", style: Theme.of(context).textTheme.bodyText1!, maxLines: 1), ), SizedBox( height: 6, ) ], ), ), Padding( padding: const EdgeInsets.all(12.0), child: PrimaryButton( width: 93, height: 35, content: "开始跑步", callback: () { startRun(context); }, ), ), // Text( // "小功能合集", // style: Theme.of(context) // .textTheme // .subtitle1 // .copyWith(fontSize: 16.0, fontWeight: FontWeight.w600), // ), // Expanded( // child: Padding( // padding: EdgeInsets.only(right: 12.0), // child: Row( // mainAxisAlignment: MainAxisAlignment.end, // children: [arrowRight5()], // ), // )), ], ); } } class FunctionSet extends StatelessWidget { List map = [ { "name": "户外跑步", "url": "function_icon_run.png", "callBack": (context) { startRun(context); }, }, { "name": "实时计步", "url": "function_icon_steps.png", "callBack": (context) { NavigatorUtil.goPage(context, (context) => StepRealTimePage()); }, }, // { // "name": "体重填写", // "url": "function_icon_weight.png", // "callBack": (context) { // NavigatorUtil.goPage(context, (context) => WeightPage(update: true,)); // }, // } ]; @override Widget build(BuildContext context) { return Expanded( child: Padding( padding: EdgeInsets.fromLTRB(15.0, 0, 15.0, 0), child: GridView( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, crossAxisSpacing: 12.0, ), children: map .map((e) => GestureDetector( onTap: () { e['callBack'](context); }, child: Container( decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(5.0))), child: Column( children: [ Padding( padding: EdgeInsets.fromLTRB(22.0, 12.0, 22.0, 8.0), child: Image.asset( "lib/assets/img/${e["url"]}", width: 56.0, height: 56.0, ), ), Text( "${e['name']}", style: TextStyle(color: Color(0xff000000)), ) ], ), ), )) .toList(), // itemBuilder: (context, index) { // return Container( // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.all(Radius.circular(5.0))), // height: 116, // child: Column( // children: [ // Padding( // padding: EdgeInsets.fromLTRB(22.0, 12.0, 22.0, 8.0), // child: Image.asset( // "lib/assets/img/function_icon_run.png", // width: 56.0, // height: 56.0, // ), // ), // Text( // "户外跑步", // style: TextStyle(color: Color(0xff000000)), // ) // ], // ), // ); // }, // itemCount: 3, ), ), ); } }