2024-09-02 ほぼOK
This commit is contained in:
@ -13,6 +13,11 @@ class DatabaseHelper {
|
||||
static Database? _database;
|
||||
Future<Database> get database async => _database ??= await _initDatabase();
|
||||
|
||||
// データベース初期化:
|
||||
//
|
||||
// シングルトンパターンを使用してDatabaseHelperのインスタンスを管理しています。
|
||||
// _initDatabase()メソッドでデータベースを初期化し、必要なテーブルを作成します。
|
||||
//
|
||||
Future<Database> _initDatabase() async {
|
||||
Directory documentDirectory = await getApplicationDocumentsDirectory();
|
||||
String path = join(documentDirectory.path, 'rog.db');
|
||||
@ -30,7 +35,10 @@ class DatabaseHelper {
|
||||
onCreate: _onCreate);
|
||||
}
|
||||
|
||||
// DBを初期化する際に、必要なテーブルを作成します。
|
||||
//
|
||||
Future _onCreate(Database db, int version) async {
|
||||
// destinationテーブル: 目的地の情報を保存(位置、名前、住所、連絡先情報など)。
|
||||
await db.execute('''
|
||||
CREATE TABLE destination(
|
||||
location_id INTEGER PRIMARY KEY,
|
||||
@ -63,6 +71,7 @@ class DatabaseHelper {
|
||||
)
|
||||
''');
|
||||
|
||||
// rogainingテーブル: ロゲイニング(orienteering的なアクティビティ)の記録を保存。
|
||||
await db.execute('''
|
||||
CREATE TABLE rogaining(
|
||||
rog_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@ -76,6 +85,7 @@ class DatabaseHelper {
|
||||
)
|
||||
''');
|
||||
|
||||
// rogテーブル: ロゲイニングのチェックポイント情報を保存。
|
||||
await db.execute('''
|
||||
CREATE TABLE rog(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@ -138,6 +148,22 @@ class DatabaseHelper {
|
||||
await db.delete('rog');
|
||||
}
|
||||
|
||||
Future<void> deleteAllRogainingExceptToday() async {
|
||||
Database db = await instance.database;
|
||||
|
||||
// 今日の開始時刻をエポックミリ秒で取得
|
||||
final now = DateTime.now();
|
||||
final startOfDay = DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
|
||||
|
||||
// 今日チェックインしたもの以外を削除
|
||||
await db.delete(
|
||||
'rog',
|
||||
where: 'checkintime < ?',
|
||||
whereArgs: [startOfDay]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Future<bool> isRogAlreadyAvailable(int id) async {
|
||||
Database db = await instance.database;
|
||||
var rog = await db.query('rog', where: "id = $id");
|
||||
@ -229,6 +255,27 @@ class DatabaseHelper {
|
||||
await db.delete('destination');
|
||||
}
|
||||
|
||||
Future<void> deleteAllDestinationsExceptTodayCheckins() async {
|
||||
Database db = await instance.database;
|
||||
|
||||
// 今日の開始時刻をエポックからのミリ秒で取得
|
||||
final now = DateTime.now();
|
||||
final startOfDay = DateTime(now.year, now.month, now.day).millisecondsSinceEpoch;
|
||||
|
||||
// 今日チェックインされ、buy_pointを持つ目的地を除いて全て削除
|
||||
await db.rawDelete('''
|
||||
DELETE FROM destination
|
||||
WHERE location_id NOT IN (
|
||||
SELECT d.location_id
|
||||
FROM destination d
|
||||
JOIN rog r ON d.location_id = r.cp_number
|
||||
WHERE date(r.checkintime / 1000, 'unixepoch', 'localtime') = date('now', 'localtime')
|
||||
AND d.buy_point > 0
|
||||
AND d.checkedin = 1
|
||||
)
|
||||
''', [startOfDay]);
|
||||
}
|
||||
|
||||
Future<bool> isAlreadyAvailable(int locationId) async {
|
||||
Database db = await instance.database;
|
||||
var dest =
|
||||
|
||||
@ -129,20 +129,25 @@ class LocationController extends GetxController {
|
||||
|
||||
// 現在位置を調整するメソッドを追加
|
||||
LatLng? adjustCurrentLocation(Position? position) {
|
||||
if (position == null) {
|
||||
if (position == null) { // positionがnullなら、lastValidLocationを使用する。
|
||||
if( lastValidLocation!=null ) {
|
||||
debugPrint("== 現在位置なし。最後の位置を使用 ==");
|
||||
//debugPrint("=== adjustCurrentLocation (Position:Null and using LastValidLocation ${lastValidLocation})===");
|
||||
return LatLng(lastValidLocation!.latitude, lastValidLocation!.longitude);
|
||||
}else {
|
||||
print("=== adjustCurrentLocation (Position:Null and No LastValidLocation ... )===");
|
||||
debugPrint("== 現在位置なし。最後の位置も無し ==");
|
||||
//print("=== adjustCurrentLocation (Position:Null and No LastValidLocation ... )===");
|
||||
return null;
|
||||
}
|
||||
//return lastValidLocation ?? LatLng(0, 0);
|
||||
}
|
||||
final signalStrength = getGpsSignalStrength(position);
|
||||
if (signalStrength == 'high' || signalStrength == 'medium') {
|
||||
debugPrint("== 信号強度 ${signalStrength} ==> 最新位置を使用 ==");
|
||||
//debugPrint("=== adjustCurrentLocation (Position:Get and return Valid location:${position} ... )===");
|
||||
lastValidLocation = LatLng(position.latitude, position.longitude);
|
||||
}else{
|
||||
debugPrint("== 信号強度 ${signalStrength} ==> 最後の位置を使用 ==");
|
||||
}
|
||||
return lastValidLocation ?? LatLng(lastValidLocation!.latitude, lastValidLocation!.longitude);
|
||||
}
|
||||
@ -169,10 +174,39 @@ class LocationController extends GetxController {
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// Start listening to location updates when the controller is initialized
|
||||
startPositionStream();
|
||||
_initLocationService();
|
||||
|
||||
}
|
||||
|
||||
Future<void> _initLocationService() async {
|
||||
try {
|
||||
bool serviceEnabled;
|
||||
LocationPermission permission;
|
||||
|
||||
serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!serviceEnabled) {
|
||||
return Future.error('Location services are disabled.');
|
||||
}
|
||||
|
||||
permission = await Geolocator.checkPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
permission = await Geolocator.requestPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
return Future.error('Location permissions are denied');
|
||||
}
|
||||
}
|
||||
|
||||
if (permission == LocationPermission.deniedForever) {
|
||||
return Future.error(
|
||||
'Location permissions are permanently denied, we cannot request permissions.');
|
||||
}
|
||||
|
||||
startPositionStream();
|
||||
} catch( e ){
|
||||
print('Error initializing location service: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// 位置情報のストリームを開始するメソッドです。
|
||||
// 位置情報サービスが有効か確認し、無効な場合はダイアログを表示します。
|
||||
// 位置情報の権限を確認し、必要な権限がない場合は権限をリクエストします。
|
||||
@ -185,7 +219,26 @@ class LocationController extends GetxController {
|
||||
// 2024-4-8 Akira : See 2809
|
||||
// stopPositionStreamメソッドを追加して、既存のストリームをキャンセルするようにしました。また、ストリームが完了したらnullに設定し、エラー発生時にストリームをキャンセルするようにしました。
|
||||
//
|
||||
void startPositionStream() async {
|
||||
void startPositionStream() {
|
||||
positionStream = Geolocator.getPositionStream(
|
||||
locationSettings: const LocationSettings(
|
||||
accuracy: LocationAccuracy.high,
|
||||
distanceFilter: 5, //10, 10mから5mに変更
|
||||
),
|
||||
).listen((Position position) {
|
||||
currentPosition.value = position;
|
||||
//debugPrint("== startPositionStream: ${position} ==");
|
||||
locationMarkerPositionStreamController.add(
|
||||
LocationMarkerPosition(
|
||||
latitude: position.latitude,
|
||||
longitude: position.longitude,
|
||||
accuracy: position.accuracy,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void startPositionStream_old() async {
|
||||
// Check for location service and permissions before starting the stream
|
||||
// 位置情報サービスの有効性をチェックし、無効な場合はエラーハンドリングを行います。
|
||||
//
|
||||
|
||||
89
lib/utils/memory_monitor.dart
Normal file
89
lib/utils/memory_monitor.dart
Normal file
@ -0,0 +1,89 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'dart:async';
|
||||
|
||||
void _performMemoryCleanup() {
|
||||
//debugPrint('Performing memory cleanup');
|
||||
|
||||
// キャッシュのクリア
|
||||
Get.deleteAll(); // GetXを使用している場合、すべてのコントローラをクリア
|
||||
imageCache.clear(); // 画像キャッシュをクリア
|
||||
imageCache.clearLiveImages(); // 使用中の画像キャッシュをクリア
|
||||
|
||||
// 大きなオブジェクトの解放
|
||||
_clearLargeObjects();
|
||||
|
||||
// 未使用のリソースの解放
|
||||
_releaseUnusedResources();
|
||||
|
||||
// ガベージコレクションの促進
|
||||
_forceGarbageCollection();
|
||||
|
||||
debugPrint('Memory cleanup completed');
|
||||
}
|
||||
|
||||
void _clearLargeObjects() {
|
||||
// 大きなリストやマップをクリア
|
||||
// 例: myLargeList.clear();
|
||||
// 例: myLargeMap.clear();
|
||||
}
|
||||
|
||||
void _releaseUnusedResources() {
|
||||
// 使用していないストリームのクローズ
|
||||
// 例: myStream?.close();
|
||||
|
||||
// 未使用のアニメーションコントローラーの破棄
|
||||
// 例: myAnimationController?.dispose();
|
||||
|
||||
// テキスト編集コントローラーの破棄
|
||||
// 例: myTextEditingController?.dispose();
|
||||
}
|
||||
|
||||
void _forceGarbageCollection() {
|
||||
// Dart VMにガベージコレクションを促す
|
||||
Timer(const Duration(seconds: 1), () {
|
||||
//debugPrint('Forcing garbage collection');
|
||||
// この呼び出しは必ずしもガベージコレクションを即座に実行するわけではありませんが、
|
||||
// Dart VMにガベージコレクションの実行を強く促します。
|
||||
// ignore: dead_code
|
||||
bool didRun = false;
|
||||
assert(() {
|
||||
didRun = true;
|
||||
return true;
|
||||
}());
|
||||
if (didRun) {
|
||||
//debugPrint('Garbage collection forced in debug mode');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// メモリ使用量を監視し、必要に応じてクリーンアップを実行する関数
|
||||
void startMemoryMonitoring() {
|
||||
const Duration checkInterval = Duration(minutes: 5);
|
||||
Timer.periodic(checkInterval, (Timer timer) {
|
||||
_checkMemoryUsage();
|
||||
});
|
||||
}
|
||||
|
||||
void _checkMemoryUsage() async {
|
||||
// ここでメモリ使用量をチェックするロジックを実装
|
||||
// 例えば、プラットフォーム固有の方法でメモリ使用量を取得する
|
||||
|
||||
// 仮の閾値(実際のアプリケーションに応じて調整が必要)
|
||||
const int memoryThreshold = 100 * 1024 * 1024; // 100 MB
|
||||
|
||||
// 仮のメモリ使用量チェック(実際の実装に置き換える必要があります)
|
||||
int currentMemoryUsage = await _getCurrentMemoryUsage();
|
||||
|
||||
if (currentMemoryUsage > memoryThreshold) {
|
||||
debugPrint('High memory usage detected: $currentMemoryUsage bytes');
|
||||
_performMemoryCleanup();
|
||||
}
|
||||
}
|
||||
|
||||
Future<int> _getCurrentMemoryUsage() async {
|
||||
// プラットフォーム固有のメモリ使用量取得ロジックを実装
|
||||
// この例では仮の値を返しています
|
||||
return 150 * 1024 * 1024; // 仮に150MBとする
|
||||
}
|
||||
Reference in New Issue
Block a user