import 'dart:io'; import 'package:decimal/decimal.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:install_plugin/install_plugin.dart'; import 'package:package_info/package_info.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:sk_base_mobile/apis/api.dart'; import 'package:sk_base_mobile/app_theme.dart'; import 'package:sk_base_mobile/config.dart'; import 'package:sk_base_mobile/models/app_config.dart'; import 'package:sk_base_mobile/router/router.util.dart'; import 'package:sk_base_mobile/services/service.dart'; import 'package:sk_base_mobile/util/device.util.dart'; import 'package:sk_base_mobile/util/logger_util.dart'; import 'package:sk_base_mobile/util/modal.util.dart'; import 'package:sk_base_mobile/util/screen_adaper_util.dart'; import 'package:sk_base_mobile/util/snack_bar.util.dart'; import 'package:sk_base_mobile/widgets/upgrade_confirm.dart'; import '../constants/constants.dart'; import 'package:dio/dio.dart'; import 'package:path_provider/path_provider.dart'; class AppInfoService extends GetxService { static AppInfoService get to => Get.find(); final versionNumber = RxString(''); late AppConfig appConfig; final scale = RxDouble(1.0); final isLarge = RxBool(false); final isCameraing = RxBool(false); final downloadProgress = RxDouble(0.0); Future init() async { LoggerUtil() .info("[service-appInfo] Register app-related information service"); try { await Future.wait([ getDeviceInfo(), getPackageInfo() /* , getAppConfig(), getossPolicy() */ ]); requestPermission(); } catch (e) { LoggerUtil().error(e); } return this; } Future setIsFirstInstall() async { await StorageService.to .setBool(CacheKeys.isFirstInstall, true, isWithUser: false); } bool checkIsFirstInstall() { bool? isFirstInstallCache = StorageService.to.getBool(CacheKeys.isFirstInstall, isWithUser: false); return isFirstInstallCache == null || !isFirstInstallCache; } Future getDeviceInfo() async { // DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); // if (Platform.isIOS) { // iosDeviceInfo = await deviceInfo.iosInfo; // if (iosDeviceInfo != null) { // await StorageService.to.setString( // CacheKeys.deviceUUID, iosDeviceInfo!.identifierForVendor!, // isWithUser: false); // await StorageService.to.setString( // CacheKeys.deviceModel, iosDeviceInfo!.name, // isWithUser: false); // } // } else { // androidDeviceInfo = await deviceInfo.androidInfo; // await StorageService.to.setString( // CacheKeys.deviceUUID, GloablConfig.DEVICE_UUID, // isWithUser: false); // await StorageService.to.setString( // CacheKeys.deviceModel, GloablConfig.DEVICE_MODEL, // isWithUser: false); // } } Future getPackageInfo() async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); versionNumber.value = packageInfo.version; } Future getAppConfig() async { // if (StorageService.to.getString(CacheKeys.token, isWithUser: false) != // null) { // final response = await Api.getAppConfig(); // if (response.data != null) { // appConfig = AppConfig.fromJson(response.data['data']); // await StorageService.to.setString( // CacheKeys.appConfig, jsonEncode(appConfig.items!), // isWithUser: false); // if (appConfig.ver != null) { // await StorageService.to // .setString(CacheKeys.ver, appConfig.ver!, isWithUser: false); // } // } // } } // need token Future getossPolicy() async { // if (StorageService.to.getString(CacheKeys.token, isWithUser: false) != // null) { // final response = await Api.getOssPolicy(); // if (response.data != null) { // ossPolicy = OssPolicy.fromJson(response.data['data']); // } // } } Future checkVersion({forceCheck = false}) async { final res = await Future.wait([ Api.getSystemParamConfigByCode(SystemParamConfig.appVersion), Api.getSystemParamConfigByCode(SystemParamConfig.isForceUpgrade) ]); final newVersion = res[0].data; final isForceUpgrade = res[1].data; if (newVersion != null) { final currentVersion = await DeviceUtil.getAppVersion(); if (newVersion != currentVersion) { ModalUtil.alert( // title: '有新版本', builder: (_) => UpgradeConfirm( version: newVersion, onConfirm: () { upgradeApp(newVersion); }, forceUpgrade: isForceUpgrade == '1', ), // contentText: isForceUpgrade == '1' ? '此版本非常重要,强制更新' : '请更新', ); } else if (forceCheck) { SnackBarUtil().info('已经是最新版本'); } } } Future upgradeApp(String version) async { if (await checkPermission()) { /// 下载安卓更新包 String url = '${GloablConfig.OSS_URL}/upload/shankuangtong_v$version.apk'; /// 创建存储文件 Directory? storageDir = await getExternalStorageDirectory(); if (storageDir != null) { String storagePath = storageDir.path; File file = File('$storagePath/shankuangtong_v${version}.apk'); if (!file.existsSync()) { file.createSync(); } try { /// 下载 downloadProgress.value = 0; await RouterUtil.back(); ModalUtil.alert( barrierDismissible: false, contentPadding: EdgeInsets.symmetric(vertical: 0), showActions: false, content: // 进度条 Obx( () => Stack( children: [ SizedBox( height: ScreenAdaper.height(40), child: LinearProgressIndicator( value: downloadProgress.value, ), ), Positioned( left: 0, right: 0, child: Text( '${downloadProgress.value * 100}%', textAlign: TextAlign.center, style: TextStyle(fontSize: ScreenAdaper.height(30)), )) ], ), )); await DioService.dio.download(url, file.path, onReceiveProgress: (num received, num total) => onReceiveProgress(received, total), options: Options( responseType: ResponseType.bytes, followRedirects: false, )); await RouterUtil.back(); InstallPlugin.install( file.path, ).then((result) {}).catchError((error) {}); } catch (e) { SnackBarUtil().warning('暂时无法更新,请重新下载安装, 或者请联系管理员'); } } } } /// 展示下载进度 void onReceiveProgress(num received, num total) { if (total != -1) { downloadProgress.value = Decimal.parse((received / total).toStringAsFixed(2)) .toDouble() .toPrecision(2); } } /// 检查是否有权限,用于安卓 Future checkPermission() async { if (await DeviceUtil.getPlatForm() == 'android') { // 检查是否有storage权限,没有的话请求权限 if (await Permission.storage.request().isGranted) { return true; // PermissionStatus permission = await PermissionHandler() // .checkPermissionStatus(PermissionGroup.storage); // if (permission != PermissionStatus.granted) { // Map permissions = // await PermissionHandler() // .requestPermissions([PermissionGroup.storage]); // if (permissions[PermissionGroup.storage] == PermissionStatus.granted) { // return true; // } } else { return false; } } return false; } T getConfigByCode(String code) { List items = appConfig.items!; dynamic config = items.firstWhereOrNull((element) => element.name == code); if (config != null) { return config.data as T; } return '' as T; } void changeTextScale(bool? value) { if (value ?? false) { scale(1.2); } else { scale(1.0); } isLarge.value = value ?? false; } Future requestPermission() async { // final status = await AppTrackingTransparency.trackingAuthorizationStatus; // if (status != TrackingStatus.authorized) { // await Future.delayed(const Duration(seconds: 2)); // await AppTrackingTransparency.requestTrackingAuthorization(); // } } }