263 lines
8.8 KiB
Dart
263 lines
8.8 KiB
Dart
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/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<AppInfoService> 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<void> 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<void> 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<void> getPackageInfo() async {
|
||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||
versionNumber.value = packageInfo.version;
|
||
}
|
||
|
||
Future<void> 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<void> 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<void> 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(
|
||
onConfirm: () {
|
||
upgradeApp(newVersion);
|
||
},
|
||
forceUpgrade: isForceUpgrade == '1',
|
||
),
|
||
// contentText: isForceUpgrade == '1' ? '此版本非常重要,强制更新' : '请更新',
|
||
);
|
||
} else if (forceCheck) {
|
||
SnackBarUtil().info('已经是最新版本');
|
||
}
|
||
}
|
||
}
|
||
|
||
Future<void> 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;
|
||
Get.back();
|
||
|
||
ModalUtil.alert(
|
||
barrierDismissible: false,
|
||
contentPadding: EdgeInsets.symmetric(vertical: 0),
|
||
showActions: false,
|
||
content:
|
||
// 进度条
|
||
Obx(
|
||
() => Stack(
|
||
children: [
|
||
Container(
|
||
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,
|
||
));
|
||
Get.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<bool> 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<PermissionGroup, PermissionStatus> permissions =
|
||
// await PermissionHandler()
|
||
// .requestPermissions([PermissionGroup.storage]);
|
||
// if (permissions[PermissionGroup.storage] == PermissionStatus.granted) {
|
||
// return true;
|
||
// }
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
T getConfigByCode<T>(String code) {
|
||
List<AppConfigItem> 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<void> requestPermission() async {
|
||
// final status = await AppTrackingTransparency.trackingAuthorizationStatus;
|
||
// if (status != TrackingStatus.authorized) {
|
||
// await Future.delayed(const Duration(seconds: 2));
|
||
// await AppTrackingTransparency.requestTrackingAuthorization();
|
||
// }
|
||
}
|
||
}
|