2024-09-02 ほぼOK
This commit is contained in:
721
lib/main.dart
721
lib/main.dart
@ -38,8 +38,10 @@ import 'pages/permission/permission.dart';
|
||||
import 'package:gifunavi/services/api_service.dart';
|
||||
|
||||
import 'package:gifunavi/provider/cached_tile_provider.dart';
|
||||
import 'package:gifunavi/pages/entry/entry_controller.dart';
|
||||
import 'package:gifunavi/pages/team/team_controller.dart';
|
||||
//import 'package:gifunavi/pages/entry/entry_controller.dart';
|
||||
//import 'package:gifunavi/pages/team/team_controller.dart';
|
||||
|
||||
import 'package:timezone/timezone.dart' as tz;
|
||||
|
||||
Map<String, dynamic> deviceInfo = {};
|
||||
|
||||
@ -56,14 +58,25 @@ void saveGameState() async {
|
||||
*/
|
||||
|
||||
// 現在のユーザーのIDも一緒に保存するようにします。
|
||||
void saveGameState() async {
|
||||
Future<void> saveGameState() async {
|
||||
DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
IndexController indexController = Get.find<IndexController>();
|
||||
SharedPreferences pref = await SharedPreferences.getInstance();
|
||||
debugPrint("indexController.currentUser = ${indexController.currentUser}");
|
||||
debugPrint("ゲームステータス保存 = ${indexController.currentUser}");
|
||||
if(indexController.currentUser.isNotEmpty) {
|
||||
pref.setInt("user_id", indexController.currentUser[0]["user"]["id"]);
|
||||
|
||||
if(indexController.currentUser[0]["user"]["event_date"]!=null) {
|
||||
final date = indexController.currentUser[0]["user"]["event_date"];
|
||||
pref.setString('eventDate', date.toIso8601String());
|
||||
debugPrint("Saved date is ${date} => ${date.toIso8601String()}");
|
||||
pref.setString('eventCode', indexController.currentUser[0]["user"]["event_code"]);
|
||||
pref.setString('teamName', indexController.currentUser[0]["user"]["team_name"]);
|
||||
pref.setString('group', indexController.currentUser[0]["user"]["group"]);
|
||||
//final zekken = indexController.currentUser[0]["user"]["zekken_number"];
|
||||
pref.setInt('zekkenNumber', indexController.currentUser[0]["user"]["zekken_number"]);
|
||||
}
|
||||
}else{
|
||||
debugPrint("User is empty....");
|
||||
}
|
||||
@ -73,75 +86,118 @@ void saveGameState() async {
|
||||
pref.setBool("ready_for_goal", DestinationController.ready_for_goal);
|
||||
}
|
||||
|
||||
/*
|
||||
void restoreGame() async {
|
||||
SharedPreferences pref = await SharedPreferences.getInstance();
|
||||
DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isInRog.value = pref.getBool("is_in_rog") ?? false;
|
||||
destinationController.rogainingCounted.value =
|
||||
pref.getBool("rogaining_counted") ?? false;
|
||||
DestinationController.ready_for_goal =
|
||||
pref.getBool("ready_for_goal") ?? false;
|
||||
//print(
|
||||
// "--restored -- destinationController.isInRog.value ${pref.getBool("is_in_rog")} -- ${pref.getBool("rogaining_counted")}");
|
||||
}
|
||||
*/
|
||||
|
||||
void restoreGame() async {
|
||||
|
||||
// _indexController.currentUser[0]["user"]["event_date"] = entryDate; // 追加2024-8-9
|
||||
// _indexController.currentUser[0]["user"]["event_code"] = entry.event.eventName;
|
||||
// _indexController.currentUser[0]["user"]["team_name"] = entry.team.teamName;
|
||||
// _indexController.currentUser[0]["user"]["group"] = entry.team.category.categoryName;
|
||||
// _indexController.currentUser[0]["user"]["zekken_number"] = entry.zekkenNumber;
|
||||
|
||||
Future<void> restoreGame() async {
|
||||
SharedPreferences pref = await SharedPreferences.getInstance();
|
||||
|
||||
IndexController indexController = Get.find<IndexController>();
|
||||
int? savedUserId = pref.getInt("user_id");
|
||||
//int? currUserId = indexController.currentUser[0]['user']['id'];
|
||||
//debugPrint("savedUserId=${savedUserId}, currentUser=${currUserId}");
|
||||
debugPrint("ゲームステータス再現 savedUserId=${savedUserId}");
|
||||
if (indexController.currentUser.isNotEmpty &&
|
||||
indexController.currentUser[0]["user"]["id"] == savedUserId) {
|
||||
DestinationController destinationController =
|
||||
Get.find<DestinationController>();
|
||||
|
||||
final dateString = pref.getString('eventDate');
|
||||
if (dateString != null) {
|
||||
final parsedDate = DateTime.parse(dateString);
|
||||
final jstDate = tz.TZDateTime.from(parsedDate, tz.getLocation('Asia/Tokyo'));
|
||||
debugPrint("restore date is ${dateString} => ${jstDate}");
|
||||
indexController.currentUser[0]["user"]["event_date"] = jstDate;
|
||||
//indexController.currentUser[0]["user"]["event_date"] = DateTime.parse(dateString);
|
||||
}
|
||||
//debugPrint("restore date is ${dateString?} => ${DateTime.parse(dateString)}");
|
||||
|
||||
indexController.currentUser[0]["user"]["event_code"] = pref.getString('eventCode');
|
||||
indexController.currentUser[0]["user"]["team_name"] = pref.getString('teamName');
|
||||
indexController.currentUser[0]["user"]["group"] = pref.getString('group');
|
||||
indexController.currentUser[0]["user"]["zekken_number"] = pref.getInt('zekkenNumber');
|
||||
|
||||
debugPrint("user = ${indexController.currentUser[0]["user"]}");
|
||||
|
||||
DestinationController destinationController = Get.find<DestinationController>();
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isInRog.value = pref.getBool("is_in_rog") ?? false;
|
||||
destinationController.rogainingCounted.value =
|
||||
pref.getBool("rogaining_counted") ?? false;
|
||||
DestinationController.ready_for_goal =
|
||||
pref.getBool("ready_for_goal") ?? false;
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
destinationController.rogainingCounted.value = pref.getBool("rogaining_counted") ?? false;
|
||||
DestinationController.ready_for_goal = pref.getBool("ready_for_goal") ?? false;
|
||||
//await Get.putAsync(() => ApiService().init());
|
||||
|
||||
if (indexController.currentUser[0]["user"]["event_code"] != null) {
|
||||
indexController.setSelectedEventName(indexController.currentUser[0]["user"]["event_code"]);
|
||||
} else {
|
||||
indexController.setSelectedEventName('未参加');
|
||||
}
|
||||
|
||||
}else{
|
||||
indexController.setSelectedEventName('未参加');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void restoreGame_new() async {
|
||||
SharedPreferences pref = await SharedPreferences.getInstance();
|
||||
IndexController indexController = Get.find<IndexController>();
|
||||
|
||||
DestinationController destinationController = Get.find<DestinationController>();
|
||||
destinationController.skipGps = false;
|
||||
destinationController.isInRog.value = pref.getBool("is_in_rog") ?? false;
|
||||
destinationController.rogainingCounted.value = pref.getBool("rogaining_counted") ?? false;
|
||||
DestinationController.ready_for_goal = pref.getBool("ready_for_goal") ?? false;
|
||||
|
||||
int? savedUserId = pref.getInt("user_id");
|
||||
if (indexController.currentUser.isNotEmpty && indexController.currentUser[0]["user"]["id"] == savedUserId) {
|
||||
final dateString = pref.getString('eventDate');
|
||||
if (dateString != null) {
|
||||
indexController.currentUser[0]["user"]["event_date"] = DateTime.parse(dateString);
|
||||
}
|
||||
indexController.currentUser[0]["user"]["event_code"] = pref.getString('eventCode');
|
||||
indexController.currentUser[0]["user"]["team_name"] = pref.getString('teamName');
|
||||
indexController.currentUser[0]["user"]["group"] = pref.getString('group');
|
||||
indexController.currentUser[0]["user"]["zekken_number"] = pref.getInt('zekkenNumber');
|
||||
|
||||
if (indexController.currentUser[0]["user"]["event_code"] != null) {
|
||||
indexController.setSelectedEventName(indexController.currentUser[0]["user"]["event_code"]);
|
||||
} else {
|
||||
indexController.setSelectedEventName('未参加');
|
||||
_showEventSelectionWarning();
|
||||
Get.toNamed(AppPages.EVENT_ENTRY);
|
||||
}
|
||||
} else {
|
||||
indexController.setSelectedEventName('未参加');
|
||||
_showEventSelectionWarning();
|
||||
Get.toNamed(AppPages.EVENT_ENTRY);
|
||||
}
|
||||
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
void _showEventSelectionWarning() {
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
title: Text('警告'),
|
||||
content: Text('イベントを選択してください。'),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('OK'),
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
Get.put(LocationController());
|
||||
/*
|
||||
Get.put(ApiService());
|
||||
Get.put(TeamController());
|
||||
Get.put(EntryController());
|
||||
Get.put(IndexController());
|
||||
*/
|
||||
/*
|
||||
await FlutterMapTileCaching.initialise();
|
||||
|
||||
final StoreDirectory instanceA = FMTC.instance('OpenStreetMap (A)');
|
||||
await instanceA.manage.createAsync();
|
||||
await instanceA.metadata.addAsync(
|
||||
key: 'sourceURL',
|
||||
value: 'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
|
||||
);
|
||||
await instanceA.metadata.addAsync(
|
||||
key: 'validDuration',
|
||||
value: '14',
|
||||
);
|
||||
await instanceA.metadata.addAsync(
|
||||
key: 'behaviour',
|
||||
value: 'cacheFirst',
|
||||
);
|
||||
*/
|
||||
// 新しいキャッシュプロバイダーの初期化
|
||||
await CacheProvider.initialize();
|
||||
|
||||
// 使用不可
|
||||
//deviceInfo = await DeviceInfoService.getDeviceInfo();
|
||||
final IndexController _indexController;
|
||||
|
||||
FlutterError.onError = (FlutterErrorDetails details) {
|
||||
FlutterError.presentError(details);
|
||||
@ -150,67 +206,98 @@ void main() async {
|
||||
ErrorService.reportError(details.exception, details.stack ?? StackTrace.current, deviceInfo, LogManager().operationLogs);
|
||||
};
|
||||
|
||||
//Get.put(LocationController());
|
||||
|
||||
//await PermissionController.checkAndRequestPermissions();
|
||||
//requestLocationPermission();
|
||||
|
||||
|
||||
|
||||
// startMemoryMonitoring(); // 2024-4-8 Akira: メモリ使用量のチェックを開始 See #2810
|
||||
Get.put(SettingsController()); // これを追加
|
||||
|
||||
|
||||
/*
|
||||
runZonedGuarded(() {
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
}, (error, stackTrace) {
|
||||
ErrorService.reportError(error, stackTrace, deviceInfo);
|
||||
});
|
||||
*/
|
||||
|
||||
FlutterError.onError = (FlutterErrorDetails details) {
|
||||
FlutterError.presentError(details);
|
||||
debugPrint('Flutter error: ${details.exception}');
|
||||
debugPrint('Stack trace: ${details.stack}');
|
||||
};
|
||||
|
||||
try {
|
||||
tz.initializeTimeZones();
|
||||
|
||||
// ApiServiceを初期化
|
||||
//await Get.putAsync(() => ApiService().init());
|
||||
await _initApiService();
|
||||
debugPrint("1: start ApiService");
|
||||
|
||||
// すべてのコントローラーとサービスを非同期で初期化
|
||||
Get.lazyPut(() => IndexController(apiService: Get.find<ApiService>()));
|
||||
debugPrint("2: start IndexController");
|
||||
|
||||
|
||||
// その他のコントローラーを遅延初期化
|
||||
Get.lazyPut(() => SettingsController());
|
||||
debugPrint("2: start SettingsController");
|
||||
Get.lazyPut(() => DestinationController());
|
||||
debugPrint("3: start DestinationController");
|
||||
|
||||
await initServices();
|
||||
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
//runApp(HomePage()); // MyApp()からHomePage()に変更
|
||||
//runApp(const MyApp());
|
||||
}catch(e, stackTrace){
|
||||
print('Error during initialization: $e');
|
||||
print('Stack trace: $stackTrace');
|
||||
|
||||
// エラーが発生した場合、エラー画面を表示
|
||||
runApp(ErrorApp(error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> initServices() async {
|
||||
print('Starting services ...');
|
||||
try {
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
print('All services started...');
|
||||
|
||||
// 非同期処理を並列実行
|
||||
await Future.wait([
|
||||
_initTimeZone(),
|
||||
_initCacheProvider(),
|
||||
]);
|
||||
print('=== 5. Initialized TimeZone...');
|
||||
print('=== 6. CacheProvider started...');
|
||||
|
||||
Get.put(PermissionController());
|
||||
await _checkPermissions();
|
||||
debugPrint("7: start PermissionController");
|
||||
|
||||
}catch(e){
|
||||
print('Error initializing ApiService: $e');
|
||||
print('Error initializing : $e');
|
||||
}
|
||||
|
||||
try {
|
||||
Get.put(SettingsController());
|
||||
print('SettingsController initialized successfully');
|
||||
} catch (e) {
|
||||
print('Error initializing SettingsController: $e');
|
||||
}
|
||||
|
||||
print('All services started...');
|
||||
|
||||
}
|
||||
|
||||
Future<void> _initLocationController() async {
|
||||
if (!Get.isRegistered<LocationController>()) {
|
||||
Get.put(LocationController());
|
||||
}
|
||||
print('=== 1. LocationController started...');
|
||||
}
|
||||
|
||||
Future<void> _initTimeZone() async {
|
||||
tz.initializeTimeZones();
|
||||
}
|
||||
|
||||
Future<void> _initCacheProvider() async {
|
||||
await CacheProvider.initialize();
|
||||
}
|
||||
|
||||
Future<void> _checkPermissions() async {
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
}
|
||||
|
||||
Future<void> _initApiService() async {
|
||||
await Get.putAsync(() => ApiService().init());
|
||||
//Get.lazyPut(() => ApiService());
|
||||
}
|
||||
|
||||
class ErrorApp extends StatelessWidget {
|
||||
final String error;
|
||||
|
||||
const ErrorApp({super.key, required this.error});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(
|
||||
child: Text('アプリの起動中にエラーが発生しました: $error'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> requestLocationPermission() async {
|
||||
try {
|
||||
final status = await Permission.locationAlways.request();
|
||||
@ -300,70 +387,80 @@ String team_name="";
|
||||
String event_code="";
|
||||
|
||||
Future<void> startBackgroundTracking() async {
|
||||
if (Platform.isIOS && background==false) {
|
||||
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
if(indexController.currentUser.isNotEmpty) {
|
||||
team_name = indexController.currentUser[0]["user"]['team_name'];
|
||||
event_code = indexController.currentUser[0]["user"]["event_code"];
|
||||
}
|
||||
try {
|
||||
if (Platform.isIOS && background == false) {
|
||||
final IndexController indexController = Get.find<IndexController>();
|
||||
if (indexController.currentUser.isNotEmpty &&
|
||||
indexController.currentUser[0]["user"]['team_name'] != null) {
|
||||
team_name = indexController.currentUser[0]["user"]['team_name'];
|
||||
event_code = indexController.currentUser[0]["user"]["event_code"];
|
||||
}
|
||||
background = true;
|
||||
debugPrint("バックグラウンド処理を開始しました。");
|
||||
const LocationSettings locationSettings = LocationSettings(
|
||||
accuracy: LocationAccuracy.high,
|
||||
distanceFilter: 100,
|
||||
);
|
||||
debugPrint("バックグラウンド処理を開始しました。");
|
||||
const LocationSettings locationSettings = LocationSettings(
|
||||
accuracy: LocationAccuracy.high,
|
||||
distanceFilter: 100,
|
||||
);
|
||||
|
||||
try {
|
||||
positionStream = Geolocator.getPositionStream(locationSettings: locationSettings)
|
||||
.listen((Position? position) async {
|
||||
if (position != null) {
|
||||
final lat = position.latitude;
|
||||
final lng = position.longitude;
|
||||
//final timestamp = DateTime.now();
|
||||
final accuracy = position.accuracy;
|
||||
try {
|
||||
positionStream =
|
||||
Geolocator.getPositionStream(locationSettings: locationSettings)
|
||||
.listen((Position? position) async {
|
||||
if (position != null) {
|
||||
final lat = position.latitude;
|
||||
final lng = position.longitude;
|
||||
//final timestamp = DateTime.now();
|
||||
final accuracy = position.accuracy;
|
||||
|
||||
// GPS信号強度がlowの場合はスキップ
|
||||
if (accuracy > 100) {
|
||||
debugPrint("GPS signal strength is low. Skipping data saving.");
|
||||
return;
|
||||
}
|
||||
// GPS信号強度がlowの場合はスキップ
|
||||
if (accuracy > 100) {
|
||||
debugPrint(
|
||||
"GPS signal strength is low. Skipping data saving.");
|
||||
return;
|
||||
}
|
||||
|
||||
Duration difference = lastGPSCollectedTime.difference(DateTime.now())
|
||||
.abs();
|
||||
// 最後にGPS信号を取得した時刻から10秒以上経過、かつ10m以上経過(普通に歩くスピード)
|
||||
//debugPrint("時間差:${difference}");
|
||||
if (difference.inSeconds >= 10 ) {
|
||||
debugPrint("バックグラウンドでのGPS取得時の処理(10secおき) count=${difference.inSeconds}, time=${DateTime.now()}");
|
||||
Duration difference = lastGPSCollectedTime.difference(
|
||||
DateTime.now())
|
||||
.abs();
|
||||
// 最後にGPS信号を取得した時刻から10秒以上経過、かつ10m以上経過(普通に歩くスピード)
|
||||
//debugPrint("時間差:${difference}");
|
||||
if (difference.inSeconds >= 10) {
|
||||
debugPrint(
|
||||
"バックグラウンドでのGPS取得時の処理(10secおき) count=${difference
|
||||
.inSeconds}, time=${DateTime.now()}");
|
||||
|
||||
// DBにGPSデータを保存 pages/destination/destination_controller.dart
|
||||
await addGPStoDB(lat, lng);
|
||||
// DBにGPSデータを保存 pages/destination/destination_controller.dart
|
||||
await addGPStoDB(lat, lng);
|
||||
|
||||
lastGPSCollectedTime = DateTime.now();
|
||||
}
|
||||
}
|
||||
}, onError: (error) {
|
||||
if (error is LocationServiceDisabledException) {
|
||||
print('Location services are disabled');
|
||||
} else if (error is PermissionDeniedException) {
|
||||
print('Location permissions are denied');
|
||||
} else {
|
||||
print('Location Error: $error');
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error starting background tracking: $e');
|
||||
}
|
||||
}else if (Platform.isAndroid && background == false) {
|
||||
background = true;
|
||||
debugPrint("バックグラウンド処理を開始しました。");
|
||||
|
||||
try {
|
||||
// 位置情報の権限が許可されているかを確認
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
}catch(e){
|
||||
print('Error starting background tracking: $e');
|
||||
lastGPSCollectedTime = DateTime.now();
|
||||
}
|
||||
}
|
||||
}, onError: (error) {
|
||||
if (error is LocationServiceDisabledException) {
|
||||
print('Location services are disabled');
|
||||
} else if (error is PermissionDeniedException) {
|
||||
print('Location permissions are denied');
|
||||
} else {
|
||||
print('Location Error: $error');
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error starting background tracking: $e');
|
||||
}
|
||||
} else if (Platform.isAndroid && background == false) {
|
||||
background = true;
|
||||
debugPrint("バックグラウンド処理を開始しました。");
|
||||
|
||||
try {
|
||||
// 位置情報の権限が許可されているかを確認
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
} catch (e) {
|
||||
print('Error starting background tracking: $e');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error starting background tracking: $e');
|
||||
// 再試行するか、エラーを適切に処理
|
||||
}
|
||||
}
|
||||
|
||||
@ -388,20 +485,24 @@ Future<void> addGPStoDB(double la, double ln) async {
|
||||
}
|
||||
|
||||
Future<void> stopBackgroundTracking() async {
|
||||
if (Platform.isIOS && background==true) {
|
||||
background=false;
|
||||
debugPrint("バックグラウンド処理:停止しました。");
|
||||
await positionStream?.cancel();
|
||||
positionStream = null;
|
||||
}else if(Platform.isAndroid && background==true){
|
||||
background=false;
|
||||
debugPrint("バックグラウンド処理:停止しました。");
|
||||
const platform = MethodChannel('location');
|
||||
try {
|
||||
await platform.invokeMethod('stopLocationService');
|
||||
} on PlatformException catch (e) {
|
||||
print("Failed to stop location service: '${e.message}'.");
|
||||
try {
|
||||
if (Platform.isIOS && background == true) {
|
||||
background = false;
|
||||
debugPrint("バックグラウンド処理:停止しました。");
|
||||
await positionStream?.cancel();
|
||||
positionStream = null;
|
||||
} else if (Platform.isAndroid && background == true) {
|
||||
background = false;
|
||||
debugPrint("バックグラウンド処理:停止しました。");
|
||||
const platform = MethodChannel('location');
|
||||
try {
|
||||
await platform.invokeMethod('stopLocationService');
|
||||
} on PlatformException catch (e) {
|
||||
print("Failed to stop location service: '${e.message}'.");
|
||||
}
|
||||
}
|
||||
} catch(e){
|
||||
print('Error stopping background tracking: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,18 +515,22 @@ class MyApp extends StatefulWidget {
|
||||
|
||||
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
// This widget is the root of your application.
|
||||
late final LocationController _locationController;
|
||||
late final IndexController _indexController;
|
||||
late final DestinationController _destinationController;
|
||||
late final PermissionController _permissionController;
|
||||
Timer? _memoryCheckTimer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (!Get.isRegistered<LocationController>()) {
|
||||
Get.put(LocationController());
|
||||
}
|
||||
_initializeControllers();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
//_startMemoryMonitoring();
|
||||
|
||||
if (context.mounted) {
|
||||
restoreGame();
|
||||
// _restoreGameAndInitialize();
|
||||
}
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
||||
// ウィジェットが構築された後に権限をチェック
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@ -435,6 +540,105 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
debugPrint("Start MyAppState...");
|
||||
}
|
||||
|
||||
Future<void> _restoreGameAndInitialize() async {
|
||||
await restoreGame();
|
||||
// ここに他の初期化処理を追加できます
|
||||
}
|
||||
|
||||
void _initializeControllers() {
|
||||
/*
|
||||
if (!Get.isRegistered<IndexController>()) {
|
||||
_locationController = Get.put(LocationController(), permanent: true);
|
||||
}
|
||||
if (!Get.isRegistered<IndexController>()) {
|
||||
_indexController = Get.put(IndexController(apiService: Get.find<ApiService>()), permanent: true);
|
||||
}
|
||||
if (!Get.isRegistered<DestinationController>()) {
|
||||
_destinationController =
|
||||
Get.put(DestinationController(), permanent: true);
|
||||
}
|
||||
if (!Get.isRegistered<PermissionController>()) {
|
||||
_permissionController = Get.put(PermissionController());
|
||||
}
|
||||
// 他の必要なコントローラーの初期化
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
void _startMemoryMonitoring() {
|
||||
/*
|
||||
_memoryCheckTimer = Timer.periodic(const Duration(seconds: 10), (timer) {
|
||||
_checkMemoryUsage();
|
||||
});
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
void _checkMemoryUsage() async {
|
||||
final memoryInfo = await _getMemoryInfo();
|
||||
//debugPrint('Current memory usage: ${memoryInfo['used']} MB');
|
||||
if (memoryInfo['used']! > 100) { // 100MB以上使用している場合
|
||||
_performMemoryCleanup();
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, int>> _getMemoryInfo() async {
|
||||
// プラットフォーム固有のメモリ情報取得ロジックを実装
|
||||
// この例では仮の値を返しています
|
||||
return {'total': 1024, 'used': 512};
|
||||
}
|
||||
|
||||
void _performMemoryCleanup() {
|
||||
/*
|
||||
debugPrint('Performing memory cleanup');
|
||||
// キャッシュのクリア
|
||||
|
||||
Get.deleteAll(force: false); // 永続的なコントローラーを除外してキャッシュをクリア
|
||||
imageCache.clear();
|
||||
imageCache.clearLiveImages();
|
||||
|
||||
// 大きなオブジェクトの解放
|
||||
_clearLargeObjects();
|
||||
|
||||
// 未使用のリソースの解放
|
||||
_releaseUnusedResources();
|
||||
|
||||
// ガベージコレクションの促進
|
||||
_forceGarbageCollection();
|
||||
debugPrint('Performing memory cleanup');
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
void _clearLargeObjects() {
|
||||
// 大きなリストやマップをクリア
|
||||
// 例: myLargeList.clear();
|
||||
}
|
||||
|
||||
void _releaseUnusedResources() {
|
||||
// 使用していないストリームのクローズ
|
||||
// 例: myStream?.close();
|
||||
}
|
||||
|
||||
void _forceGarbageCollection() {
|
||||
/*
|
||||
Timer(const Duration(seconds: 1), () {
|
||||
debugPrint('Forcing garbage collection');
|
||||
// ignore: dead_code
|
||||
bool didRun = false;
|
||||
assert(() {
|
||||
didRun = true;
|
||||
return true;
|
||||
}());
|
||||
if (didRun) {
|
||||
debugPrint('Garbage collection forced in debug mode');
|
||||
}
|
||||
});
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void showPermissionRequiredDialog() {
|
||||
showDialog(
|
||||
@ -474,6 +678,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_memoryCheckTimer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -487,110 +692,118 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
@override
|
||||
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
|
||||
try {
|
||||
LocationController locationController = Get.find<LocationController>();
|
||||
if (!Get.isRegistered<IndexController>()) {
|
||||
_indexController = Get.find<IndexController>();
|
||||
}
|
||||
if (!Get.isRegistered<LocationController>()) {
|
||||
_locationController = Get.find<LocationController>();
|
||||
}
|
||||
if (!Get.isRegistered<DestinationController>()) {
|
||||
_destinationController = Get.find<DestinationController>();
|
||||
}
|
||||
|
||||
DestinationController destinationController = Get.find<
|
||||
DestinationController>();
|
||||
|
||||
//DestinationController destinationController =
|
||||
// Get.find<DestinationController>();
|
||||
switch (state) {
|
||||
case AppLifecycleState.resumed:
|
||||
// 追加 2024.8.13.
|
||||
await stopBackgroundTracking();
|
||||
destinationController.restartGPS();
|
||||
// 追加 2024.8.13.
|
||||
|
||||
// バックグラウンド処理を停止
|
||||
if (Platform.isIOS && destinationController.isRunningBackgroundGPS) {
|
||||
// Foreground に戻った時の処理
|
||||
debugPrint(
|
||||
" ==(Status Changed)==> RESUMED. フォアグラウンドに戻りました");
|
||||
locationController.resumePositionStream();
|
||||
//print("RESUMED");
|
||||
restoreGame();
|
||||
|
||||
stopBackgroundTracking();
|
||||
destinationController.isRunningBackgroundGPS = false;
|
||||
destinationController.restartGPS();
|
||||
} else if (Platform.isAndroid) {
|
||||
if (destinationController.isRunningBackgroundGPS) {
|
||||
const platform = MethodChannel('location');
|
||||
platform.invokeMethod('stopLocationService');
|
||||
destinationController.isRunningBackgroundGPS = false;
|
||||
destinationController.restartGPS();
|
||||
debugPrint("stopped android location service..");
|
||||
}
|
||||
|
||||
debugPrint(
|
||||
"==(Status Changed)==> RESUMED. android フォアグラウンドに戻りました");
|
||||
locationController.resumePositionStream();
|
||||
//print("RESUMED");
|
||||
restoreGame();
|
||||
} else {
|
||||
debugPrint("==(Status Changed)==> RESUMED 不明状態");
|
||||
}
|
||||
//await _onResumed();
|
||||
await _onResumed();
|
||||
break;
|
||||
case AppLifecycleState.inactive:
|
||||
|
||||
// アプリが非アクティブになったときに発生します。
|
||||
|
||||
if (Platform.isIOS && !destinationController
|
||||
.isRunningBackgroundGPS) { // iOSはバックグラウンドでもフロントの処理が生きている。
|
||||
// これは、別のアプリやシステムのオーバーレイ(着信通話やアラームなど)によって一時的に中断された状態です。
|
||||
debugPrint(" ==(Status Changed)==> INACTIVE. 非アクティブ処理。");
|
||||
//locationController.resumePositionStream();
|
||||
|
||||
// 追加: フロントエンドのGPS信号のlistenを停止
|
||||
locationController.stopPositionStream();
|
||||
|
||||
destinationController.isRunningBackgroundGPS = true;
|
||||
startBackgroundTracking();
|
||||
} else if (Platform.isAndroid &&
|
||||
!destinationController.isRunningBackgroundGPS) {
|
||||
debugPrint(" ==(Status Changed)==> INACTIVE. 非アクティブ処理。");
|
||||
} else {
|
||||
debugPrint("==(Status Changed)==> INACTIVE 不明状態");
|
||||
}
|
||||
saveGameState();
|
||||
await _onInactive();
|
||||
break;
|
||||
|
||||
case AppLifecycleState.paused:
|
||||
// バックグラウンドに移行したときの処理
|
||||
//locationController.resumePositionStream();
|
||||
debugPrint(" ==(Status Changed)==> PAUSED. バックグラウンド処理。");
|
||||
if (Platform.isIOS && !destinationController.isRunningBackgroundGPS) {
|
||||
debugPrint(
|
||||
"iOS already running background GPS processing when it's inactive");
|
||||
} else if (Platform.isAndroid &&
|
||||
!destinationController.isRunningBackgroundGPS) {
|
||||
debugPrint(
|
||||
" ==(Status Changed)==> PAUSED. Android バックグラウンド処理。");
|
||||
locationController.stopPositionStream();
|
||||
const platform = MethodChannel('location');
|
||||
platform.invokeMethod('startLocationService');
|
||||
//platform.invokeMethod('stopLocationService');
|
||||
destinationController.isRunningBackgroundGPS = true;
|
||||
//startBackgroundTracking();
|
||||
}
|
||||
saveGameState();
|
||||
await _onPaused();
|
||||
break;
|
||||
|
||||
case AppLifecycleState.detached:
|
||||
// アプリが終了する直前に発生します。この状態では、アプリはメモリから解放される予定です。
|
||||
//locationController.resumePositionStream();
|
||||
debugPrint(" ==(Status Changed)==> DETACHED アプリは終了します。");
|
||||
saveGameState();
|
||||
await _onDetached();
|
||||
break;
|
||||
|
||||
case AppLifecycleState.hidden:
|
||||
// Web用の特殊な状態で、モバイルアプリでは発生しません。
|
||||
//locationController.resumePositionStream();
|
||||
debugPrint(" ==(Status Changed)==> Hidden アプリが隠れた");
|
||||
saveGameState();
|
||||
await _onHidden();
|
||||
break;
|
||||
}
|
||||
}catch(e){
|
||||
print('Error finding LocationController: $e');
|
||||
print('Error finding didChangeAppLifecycleState: $e');
|
||||
_initializeControllers();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onResumed() async {
|
||||
debugPrint("==(Status Changed)==> RESUMED");
|
||||
try {
|
||||
_initializeControllers();
|
||||
|
||||
await stopBackgroundTracking();
|
||||
_destinationController.restartGPS();
|
||||
|
||||
if (Platform.isIOS && _destinationController.isRunningBackgroundGPS) {
|
||||
_locationController.resumePositionStream();
|
||||
await restoreGame();
|
||||
_destinationController.isRunningBackgroundGPS = false;
|
||||
} else if (Platform.isAndroid) {
|
||||
if (_destinationController.isRunningBackgroundGPS) {
|
||||
const platform = MethodChannel('location');
|
||||
await platform.invokeMethod('stopLocationService');
|
||||
_destinationController.isRunningBackgroundGPS = false;
|
||||
_destinationController.restartGPS();
|
||||
}
|
||||
_locationController.resumePositionStream();
|
||||
await restoreGame();
|
||||
}
|
||||
} catch(e) {
|
||||
print('Error in _onResumed: $e');
|
||||
// 必要に応じて再試行またはエラー処理
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onInactive() async {
|
||||
debugPrint("==(Status Changed)==> INACTIVE");
|
||||
if (Platform.isIOS && !_destinationController.isRunningBackgroundGPS) {
|
||||
debugPrint(" ==(Status Changed)==> INACTIVE. 非アクティブ処理。");
|
||||
_locationController.stopPositionStream();
|
||||
_destinationController.isRunningBackgroundGPS = true;
|
||||
await startBackgroundTracking();
|
||||
} else if (Platform.isAndroid && !_destinationController.isRunningBackgroundGPS) {
|
||||
// Android特有の処理があれば追加
|
||||
debugPrint(" ==(Status Changed)==> INACTIVE. 非アクティブ処理。");
|
||||
}else{
|
||||
debugPrint("==(Status Changed)==> INACTIVE 不明状態");
|
||||
}
|
||||
await saveGameState();
|
||||
}
|
||||
|
||||
Future<void> _onPaused() async {
|
||||
debugPrint(" ==(Status Changed)==> PAUSED. バックグラウンド処理。");
|
||||
if (Platform.isAndroid && !_destinationController.isRunningBackgroundGPS) {
|
||||
debugPrint(" ==(Status Changed)==> PAUSED. Android バックグラウンド処理。");
|
||||
_locationController.stopPositionStream();
|
||||
const platform = MethodChannel('location');
|
||||
await platform.invokeMethod('startLocationService');
|
||||
_destinationController.isRunningBackgroundGPS = true;
|
||||
}
|
||||
await saveGameState();
|
||||
}
|
||||
|
||||
Future<void> _onDetached() async {
|
||||
debugPrint(" ==(Status Changed)==> DETACHED アプリは終了します。");
|
||||
await saveGameState();
|
||||
// アプリ終了時の追加処理
|
||||
}
|
||||
|
||||
|
||||
Future<void> _onHidden() async {
|
||||
debugPrint(" ==(Status Changed)==> Hidden アプリが隠れた");
|
||||
await saveGameState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
Reference in New Issue
Block a user