| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- import 'dart:async';
- import 'dart:io';
- import 'package:assets_audio_player/assets_audio_player.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter_flavor/flutter_flavor.dart';
- import 'package:get_storage/get_storage.dart';
- import 'package:isar/isar.dart';
- import 'package:trackoffical_app/service/service.dart';
- import 'package:trackoffical_app/service/user_profile.dart';
- import 'package:nfc_manager/nfc_manager.dart';
- import 'package:package_info_plus/package_info_plus.dart';
- import 'package:permission_handler/permission_handler.dart';
- import 'package:sensor/sensor.dart' as sensor;
- import 'package:system_clock/system_clock.dart';
- import 'package:vibration/vibration.dart';
- import '../global.dart';
- import '../model/platform.dart';
- import '../logger.dart';
- import '../model/m_position.dart';
- import '../model/provider.dart';
- import 'package:trackoffical_app/pb.dart' as pb;
- import 'package:device_info_plus/device_info_plus.dart';
- import 'package:trackoffical_app/utils.dart' as utils;
- import 'package:flutter/material.dart';
- class App extends IService{
- var screenSize = Size.zero;
- static App get to => Get.find();
- static const _platform = MethodChannel('com.beswell.app/api');
- final _serverTime = _ServerTime();
- DateTime get now=>_serverTime.now();
- final userProfile = UserProfile();
- late String appVersion;
- PlatformInfo platformInfo = PlatformInfoAndroid();
- final isLocationServiceEnable = false.obs;
- final isNfcEnable = false.obs;
- var xDpi = 0.0;
- var yDpi = 0.0;
- var devicePixelRatio = 1.0;
- var isShowHomeWarn = true;
- AssetsAudioPlayer? _audioPlayer;
- double heightOneMM(){
- final dpi = xDpi;
- double pixelRatio = devicePixelRatio;
- double pixelCountInMm = dpi / pixelRatio / 25.4;
- return pixelCountInMm;
- }
- bool isFirstLocating = true;
- Future<bool> get isNfcAvailable async {
- final platform = platformInfo;
- if(platform is PlatformInfoIOS){
- if (platform.deviceVersion <8 ){
- return false;
- }
- }
- return await NfcManager.instance.isAvailable();
- }
- final List<pb.Region> regionList = [];
- correctByServerNow(DateTime serverNow)=>_serverTime.correctByServerNow(serverNow);
- Future<void> initBeforeApp()async{
- final flavor = await getFlavor();
- if(flavor == 'dev'){
- GlobalVar.apiHost='totapi-lc.beswell.com';
- GlobalVar.flavor=Flavor.dev;
- info('版本:dev');
- FlavorConfig(
- name: "开发版",
- color: Colors.red,
- location: BannerLocation.topStart,
- );
- }
- }
- @override
- Future<App> init() async {
- await GetStorage.init();
- final deviceInfoPlugin = DeviceInfoPlugin();
- final packageInfo = await PackageInfo.fromPlatform();
- appVersion = packageInfo.version;
- String buildNumber = packageInfo.buildNumber;
- info("version: $appVersion\nbuildNumber: $buildNumber");
- xDpi = await sensor.Sensor.api.getXDPI();
- yDpi = await sensor.Sensor.api.getYDPI();
- try{
- if (Platform.isAndroid){
- platformInfo = PlatformInfoAndroid();
- }
- if (Platform.isIOS){
- final iosInfo = await deviceInfoPlugin.iosInfo;
- platformInfo = iosInfo.toModel();
- info('ios信息: $iosInfo');
- }
- }catch(e){
- warn('读取设备信息失败:', e);
- }
- workCheckLocationService();
- workCheckNFCEnable();
- return this;
- }
- final Rx<MPosition?> position = Rx(null);
- final Rx<Provider?> selectedProvider = Rx(null);
- void workCheckLocationService()async{
- while(!isClosed){
- isLocationServiceEnable.value = await utils.isLocationServiceEnabled();
- await Future.delayed(100.milliseconds);
- }
- }
- void workCheckNFCEnable()async{
- while(!isClosed){
- isNfcEnable.value = await isNfcAvailable;
- await Future.delayed(100.milliseconds);
- }
- }
- Future<MPosition> getPosition({bool forceFlush=false, Duration? timeout}) async{
- if(!Platform.isIOS){
- var status = await Permission.location.status;
- if (!status.isGranted) {
- if (!await Permission.location.request().isGranted) {
- throw Exception('定位权限未获取');
- }
- }
- }
- await utils.checkLocationService();
- info('开始定位');
- var future = sensor.Sensor.getCurrentPosition();
- if(timeout!= null){
- future = future.timeout(timeout);
- }
- final p = await future;
- final p2 = MPosition(latitude: p.latitude, longitude: p.longitude);
- position.value = p2;
- return p2;
- }
- /// 设备是否支持 NFC
- Future<bool> hasNfc()async{
- return await _platform.invokeMethod('hasNfc');
- }
- /// 请求开启 NFC 并返回结果
- Future<bool> askEnableNfc()async{
- return await _platform.invokeMethod('askEnableNfc');
- }
- Future<String> getPosition2({bool forceFlush=false}) async{
- return await _platform.invokeMethod('getLocation');
- }
- /// android升级App
- Future<void> updateApp(pb.GetUpdateVersionReply info)async{
- return await _platform.invokeMethod('updateApp', {
- 'url': info.vUrl,
- 'version': info.vCode
- });
- }
- /// android升级App进度
- Future<float> getUpdateAppProcess()async{
- return await _platform.invokeMethod('getUpdateAppProcess');
- }
- /// android Flavor
- Future<String> getFlavor()async{
- if(Platform.isAndroid || Platform.isIOS){
- return await _platform.invokeMethod('getFlavor');
- }
- return '';
- }
- Future<void> soundPlayAsset(String src)async{
- soundStop();
- if(userProfile.gameSettingsSoundPrompt.value){
- _audioPlayer=AssetsAudioPlayer.newPlayer();
- await _audioPlayer!.open(
- Audio(src),
- showNotification: false,
- );
- }
- }
- void soundStop(){
- _audioPlayer?.stop();
- _audioPlayer=null;
- }
- Future<void> vibrate({
- int duration = 500,
- List<int> pattern = const [],
- int repeat = -1,
- List<int> intensities = const [],
- int amplitude = -1,
- })async{
- if(userProfile.gameSettingsVibrationPrompt.value){
- if (await Vibration.hasCustomVibrationsSupport()==true) {
- await Vibration.vibrate(duration: duration, pattern: pattern, repeat: repeat, intensities: intensities, amplitude: amplitude);
- } else {
- await Vibration.vibrate();
- }
- }
- }
- void locationStart(Duration minTime, double minDistanceM){
- sensor.Sensor.locationStart(minTime, minDistanceM);
- }
- void locationStop(){
- sensor.Sensor.api.locationStop();
- }
- Stream<MPosition> get locationStream{
- return sensor.Sensor.locationStream.map((event) => event.toModel());
- }
- }
- extension IosInfoExt on IosDeviceInfo{
- PlatformInfoIOS toModel(){
- final machine = utsname.machine;
- final info = PlatformInfoIOS();
- warn('iphone info: $info');
- if(machine != null){
- final regExp = RegExp('\\d+');
- final matches = regExp.allMatches(machine).toList();
- if (matches.isNotEmpty){
- var match = matches[0];
- try{
- info.deviceVersion = double.parse(match.group(0)!);
- }catch(e){
- warn('ios 读取手机型号失败($machine): ', e);
- }
- if (matches.length > 1){
- match = matches[1];
- try{
- info.deviceVersion += double.parse('0.${match.group(0)!}');
- }catch(e){
- warn('ios 读取手机型号失败($machine): ', e);
- }
- }
- }
- }
- return info;
- }
- }
- class _ServerTime{
- Duration? _systemOpenTimeWhenRcvServerTime;
- DateTime? _serverTime;
- correctByServerNow(DateTime serverNow){
- _systemOpenTimeWhenRcvServerTime = SystemClock.elapsedRealtime();
- _serverTime = serverNow;
- }
- DateTime now(){
- if(_systemOpenTimeWhenRcvServerTime==null){
- return DateTime.now();
- }
- return _serverTime!.add(SystemClock.elapsedRealtime() - _systemOpenTimeWhenRcvServerTime!);
- }
- }
|