Android release 4.8.2 revision 483
This commit is contained in:
@ -3,7 +3,7 @@ import 'dart:io';
|
||||
//import 'dart:convert';
|
||||
//import 'dart:developer';
|
||||
import 'package:rogapp/model/gps_data.dart';
|
||||
import 'package:rogapp/pages/home/home_page.dart';
|
||||
//import 'package:rogapp/pages/home/home_page.dart';
|
||||
import 'package:rogapp/utils/database_gps.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
|
||||
@ -141,6 +141,7 @@ void main() async {
|
||||
// startMemoryMonitoring(); // 2024-4-8 Akira: メモリ使用量のチェックを開始 See #2810
|
||||
Get.put(SettingsController()); // これを追加
|
||||
|
||||
|
||||
/*
|
||||
runZonedGuarded(() {
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
@ -149,6 +150,8 @@ void main() async {
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
|
||||
runApp(const ProviderScope(child: MyApp()));
|
||||
//runApp(HomePage()); // MyApp()からHomePage()に変更
|
||||
//runApp(const MyApp());
|
||||
@ -324,7 +327,7 @@ Future<void> addGPStoDB(double la, double ln) async {
|
||||
is_checkin: 0,
|
||||
created_at: DateTime.now().millisecondsSinceEpoch);
|
||||
var res = await db.insertGps(gps_data);
|
||||
//debugPrint("バックグラウンドでのGPS保存:");
|
||||
debugPrint("バックグラウンドでのGPS保存:");
|
||||
} catch (err) {
|
||||
print("errr ready gps ${err}");
|
||||
return;
|
||||
@ -367,52 +370,39 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
}
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
|
||||
// Add to clear
|
||||
// ウィジェットが構築された後に権限をチェック
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
showLocationDisclosure(context);
|
||||
PermissionController.checkAndRequestPermissions();
|
||||
});
|
||||
|
||||
/*
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
await PermissionController.checkAndRequestPermissions();
|
||||
});
|
||||
*/
|
||||
|
||||
debugPrint("Start MyAppState...");
|
||||
}
|
||||
|
||||
void showLocationDisclosure(BuildContext context) {
|
||||
/*
|
||||
void showPermissionRequiredDialog() {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text('位置情報の使用について'),
|
||||
content: const SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Text('このアプリでは、以下の目的で位置情報を使用します:'),
|
||||
Text('• チェックポイントの自動チェックイン(アプリが閉じているときも含む)'),
|
||||
Text('• 移動履歴の記録(バックグラウンドでも継続)'),
|
||||
Text('• 現在地周辺の情報表示'),
|
||||
Text('\nバックグラウンドでも位置情報を継続的に取得します。'),
|
||||
Text('これにより、バッテリーの消費が増加する可能性があります。'),
|
||||
],
|
||||
),
|
||||
),
|
||||
title: Text('権限が必要です'),
|
||||
content: Text('このアプリは機能するために位置情報の権限が必要です。設定で権限を許可してください。'),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('同意しない'),
|
||||
child: Text('設定を開く'),
|
||||
onPressed: () {
|
||||
openAppSettings();
|
||||
Navigator.of(context).pop();
|
||||
// アプリを終了するなどの処理
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('同意する'),
|
||||
child: Text('アプリを終了'),
|
||||
onPressed: () {
|
||||
// アプリを終了
|
||||
Navigator.of(context).pop();
|
||||
requestLocationPermission();
|
||||
// よりクリーンな終了のために 'flutter_exit_app' のようなプラグインを使用することをお勧めします
|
||||
// 今回は単にすべてのルートをポップします
|
||||
Navigator.of(context).popUntil((route) => false);
|
||||
},
|
||||
),
|
||||
],
|
||||
@ -421,6 +411,9 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
|
||||
);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
|
||||
@ -417,6 +417,7 @@ class IndexController extends GetxController with WidgetsBindingObserver {
|
||||
void register(String email, String password, BuildContext context) {
|
||||
AuthService.register(email, password).then((value) {
|
||||
if (value.isNotEmpty) {
|
||||
debugPrint("ユーザー登録成功:${email}, ${password}");
|
||||
logManager.addOperationLog("User tried to register new account : ${email} , ${password} .");
|
||||
|
||||
currentUser.clear();
|
||||
@ -425,16 +426,17 @@ class IndexController extends GetxController with WidgetsBindingObserver {
|
||||
Navigator.pop(context);
|
||||
Get.toNamed(AppPages.INDEX);
|
||||
} else {
|
||||
debugPrint("ユーザー登録失敗:${email}, ${password}");
|
||||
logManager.addOperationLog("User failed to register new account : ${email} , ${password} .");
|
||||
isLoading.value = false;
|
||||
Get.snackbar(
|
||||
'failed'.tr,
|
||||
'user_registration_failed_please_try_again'.tr,
|
||||
'failed'.tr, // 失敗
|
||||
'user_registration_failed_please_try_again'.tr, // ユーザー登録に失敗しました。
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
duration: const Duration(seconds: 3),
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
|
||||
@ -4,21 +4,174 @@ import 'package:get/get.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:rogapp/services/location_service.dart';
|
||||
import 'dart:developer' as developer;
|
||||
import 'dart:async';
|
||||
|
||||
|
||||
class PermissionController {
|
||||
|
||||
/*
|
||||
static Future<bool> checkLocationPermissions() async {
|
||||
debugPrint("(gifunavi)== checkLocationPermissions ==");
|
||||
final alwaysPermission = await Permission.locationAlways.status;
|
||||
final whenInUsePermission = await Permission.locationWhenInUse.status;
|
||||
final locationPermission = await Permission.location.status;
|
||||
static bool _isRequestingPermission = false;
|
||||
static Completer<bool>? _permissionCompleter;
|
||||
|
||||
return (alwaysPermission == PermissionStatus.granted || whenInUsePermission == PermissionStatus.granted) &&
|
||||
(locationPermission == PermissionStatus.granted);
|
||||
static Future<bool> checkLocationPermissions() async {
|
||||
final locationPermission = await Permission.location.status;
|
||||
final whenInUsePermission = await Permission.locationWhenInUse.status;
|
||||
final alwaysPermission = await Permission.locationAlways.status;
|
||||
|
||||
return locationPermission == PermissionStatus.granted &&
|
||||
(whenInUsePermission == PermissionStatus.granted || alwaysPermission == PermissionStatus.granted);
|
||||
}
|
||||
*/
|
||||
|
||||
static Future<bool> checkAndRequestPermissions() async {
|
||||
if (_isRequestingPermission) {
|
||||
return _permissionCompleter!.future;
|
||||
}
|
||||
|
||||
_isRequestingPermission = true;
|
||||
_permissionCompleter = Completer<bool>();
|
||||
|
||||
bool hasPermissions = await checkLocationPermissions();
|
||||
if (!hasPermissions) {
|
||||
bool userAgreed = await showLocationDisclosure();
|
||||
if (userAgreed) {
|
||||
try {
|
||||
await requestAllLocationPermissions();
|
||||
hasPermissions = await checkLocationPermissions();
|
||||
} catch (e) {
|
||||
print('Error requesting location permissions: $e');
|
||||
hasPermissions = false;
|
||||
}
|
||||
} else {
|
||||
print('User did not agree to location usage');
|
||||
hasPermissions = false;
|
||||
// アプリを終了
|
||||
SystemNavigator.pop();
|
||||
}
|
||||
}
|
||||
|
||||
_isRequestingPermission = false;
|
||||
_permissionCompleter!.complete(hasPermissions);
|
||||
return _permissionCompleter!.future;
|
||||
}
|
||||
|
||||
static Future<void> requestAllLocationPermissions() async {
|
||||
await Permission.location.request();
|
||||
await Permission.locationWhenInUse.request();
|
||||
await Permission.locationAlways.request();
|
||||
|
||||
if (await Permission.locationAlways.isGranted) {
|
||||
const platform = MethodChannel('location');
|
||||
try {
|
||||
await platform.invokeMethod('startLocationService');
|
||||
} on PlatformException catch (e) {
|
||||
debugPrint("Failed to start location service: '${e.message}'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> showLocationDisclosure() async {
|
||||
return await Get.dialog<bool>(
|
||||
AlertDialog(
|
||||
title: Text('位置情報の使用について'),
|
||||
content: const SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Text('このアプリでは、以下の目的で位置情報を使用します:'),
|
||||
Text('• チェックポイントの自動チェックイン(アプリが閉じているときも含む)'),
|
||||
Text('• 移動履歴の記録(バックグラウンドでも継続)'),
|
||||
Text('• 現在地周辺の情報表示'),
|
||||
Text('\nバックグラウンドでも位置情報を継続的に取得します。'),
|
||||
Text('これにより、バッテリーの消費が増加する可能性があります。'),
|
||||
Text('同意しない場合には、アプリは終了します。'),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('同意しない'),
|
||||
onPressed: () => Get.back(result: false),
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('同意する'),
|
||||
onPressed: () => Get.back(result: true),
|
||||
),
|
||||
],
|
||||
),
|
||||
barrierDismissible: false,
|
||||
) ?? false;
|
||||
}
|
||||
|
||||
static void showPermissionDeniedDialog(String title,String message) {
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
//title: Text('location_permission_needed_title'.tr),
|
||||
title: Text(title.tr),
|
||||
// 位置情報への許可が必要です
|
||||
//content: Text('location_permission_needed_main'.tr),
|
||||
content: Text(message.tr),
|
||||
// 岐阜ロゲでは、位置情報を使用してスタート・チェックイン・ゴール等の通過照明及び移動手段の記録のために、位置情報のトラッキングを行なっています。このためバックグラウンドでもトラッキングができるように位置情報の権限が必要です。
|
||||
// 設定画面で、「岐阜ナビ」に対して、常に位置情報を許可するように設定してください。
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('キャンセル'),
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
TextButton(
|
||||
child: Text('設定'),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
openAppSettings();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static Future<bool> requestLocationPermissions(BuildContext context) async {
|
||||
if (_isRequestingPermission) {
|
||||
// If a request is already in progress, wait for it to complete
|
||||
return _permissionCompleter!.future;
|
||||
}
|
||||
|
||||
_isRequestingPermission = true;
|
||||
_permissionCompleter = Completer<bool>();
|
||||
|
||||
bool userAgreed = await showLocationDisclosure(context);
|
||||
if (userAgreed) {
|
||||
try {
|
||||
final locationStatus = await Permission.location.request();
|
||||
final whenInUseStatus = await Permission.locationWhenInUse.request();
|
||||
final alwaysStatus = await Permission.locationAlways.request();
|
||||
|
||||
if (locationStatus == PermissionStatus.granted &&
|
||||
(whenInUseStatus == PermissionStatus.granted || alwaysStatus == PermissionStatus.granted)) {
|
||||
_permissionCompleter!.complete(true);
|
||||
} else {
|
||||
showPermissionDeniedDialog('location_permission_needed_title', 'location_permission_needed_main');
|
||||
_permissionCompleter!.complete(false);
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error requesting location permission: $e');
|
||||
_permissionCompleter!.complete(false);
|
||||
}
|
||||
} else {
|
||||
print('User did not agree to location usage');
|
||||
_permissionCompleter!.complete(false);
|
||||
// Exit the app
|
||||
SystemNavigator.pop();
|
||||
}
|
||||
|
||||
_isRequestingPermission = false;
|
||||
return _permissionCompleter!.future;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static Future<bool> checkStoragePermission() async {
|
||||
//debugPrint("(gifunavi)== checkStoragePermission ==");
|
||||
@ -42,6 +195,7 @@ class PermissionController {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
static Future<bool> checkLocationBasicPermission() async {
|
||||
//debugPrint("(gifunavi)== checkLocationBasicPermission ==");
|
||||
final locationPermission = await Permission.location.status;
|
||||
@ -152,31 +306,8 @@ class PermissionController {
|
||||
}
|
||||
}
|
||||
|
||||
static void showPermissionDeniedDialog(String title,String message) {
|
||||
Get.dialog(
|
||||
AlertDialog(
|
||||
//title: Text('location_permission_needed_title'.tr),
|
||||
title: Text(title.tr),
|
||||
// 位置情報への許可が必要です
|
||||
//content: Text('location_permission_needed_main'.tr),
|
||||
content: Text(message.tr),
|
||||
// 岐阜ロゲでは、位置情報を使用してスタート・チェックイン・ゴール等の通過照明及び移動手段の記録のために、位置情報のトラッキングを行なっています。このためバックグラウンドでもトラッキングができるように位置情報の権限が必要です。
|
||||
// 設定画面で、「岐阜ナビ」に対して、常に位置情報を許可するように設定してください。
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('キャンセル'),
|
||||
onPressed: () => Get.back(),
|
||||
),
|
||||
TextButton(
|
||||
child: Text('設定'),
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
openAppSettings();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@ -44,8 +44,8 @@ class RegisterPage extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Text(
|
||||
"sign_up".tr,
|
||||
style: TextStyle(
|
||||
"sign_up".tr, // "サインアップ"
|
||||
style: const TextStyle(
|
||||
fontSize: 30,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@ -54,7 +54,7 @@ class RegisterPage extends StatelessWidget {
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"create_account".tr,
|
||||
"create_account".tr, // アカウントを無料で作成します。
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: Colors.grey[700],
|
||||
@ -69,15 +69,15 @@ class RegisterPage extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 40),
|
||||
child: Column(
|
||||
children: [
|
||||
makeInput(label: "email".tr, controller: emailController),
|
||||
makeInput(label: "email".tr, controller: emailController), // メールアドレス
|
||||
makeInput(
|
||||
label: "password".tr,
|
||||
controller: passwordController,
|
||||
obsureText: true),
|
||||
obsureText: true), // パスワード
|
||||
makeInput(
|
||||
label: "confirm_password".tr,
|
||||
controller: confirmPasswordController,
|
||||
obsureText: true)
|
||||
obsureText: true) // パスワード再確認
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -99,14 +99,14 @@ class RegisterPage extends StatelessWidget {
|
||||
if (passwordController.text !=
|
||||
confirmPasswordController.text) {
|
||||
Get.snackbar(
|
||||
"No match",
|
||||
"Passwords does not match",
|
||||
"no_match".tr,
|
||||
"password_does_not_match".tr,
|
||||
backgroundColor: Colors.red,
|
||||
colorText: Colors.white,
|
||||
icon: const Icon(Icons.assistant_photo_outlined,
|
||||
size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
duration: const Duration(seconds: 3),
|
||||
// backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
@ -121,7 +121,7 @@ class RegisterPage extends StatelessWidget {
|
||||
icon: const Icon(Icons.assistant_photo_outlined,
|
||||
size: 40.0, color: Colors.blue),
|
||||
snackPosition: SnackPosition.TOP,
|
||||
duration: const Duration(milliseconds: 800),
|
||||
duration: const Duration(seconds: 3),
|
||||
//backgroundColor: Colors.yellow,
|
||||
//icon:Image(image:AssetImage("assets/images/dora.png"))
|
||||
);
|
||||
|
||||
@ -129,12 +129,14 @@ class AuthService {
|
||||
return cats;
|
||||
}
|
||||
|
||||
// ユーザー登録
|
||||
//
|
||||
static Future<Map<String, dynamic>> register(
|
||||
String email, String password) async {
|
||||
Map<String, dynamic> cats = {};
|
||||
String serverUrl = ConstValues.currentServer();
|
||||
String url = '$serverUrl/api/register/';
|
||||
//print('++++++++$url');
|
||||
debugPrint('++++++++${url}');
|
||||
final http.Response response = await http.post(
|
||||
Uri.parse(url),
|
||||
headers: <String, String>{
|
||||
|
||||
@ -30,7 +30,7 @@ class StringValues extends Translations{
|
||||
'visit_history': 'Visit History',
|
||||
'rog_web': 'rog website',
|
||||
'no_values': 'No Values',
|
||||
'email_and_password_required': 'Email and password required',
|
||||
'email_and_password_required': 'Email and password are required to register user',
|
||||
'rogaining_user_need_tosign_up': "Rogaining participants do need to sign up.",
|
||||
'add_location': 'Gifu',
|
||||
'select_travel_mode':'Select your travel mode',
|
||||
@ -211,6 +211,8 @@ class StringValues extends Translations{
|
||||
'reset_message': 'Are you ok to reset all data in this device?',
|
||||
'reset_done': 'Reset Done.',
|
||||
'reset_explain': 'All data has been reset. You should tap start rogaining to start game.',
|
||||
'no_match': 'No match!',
|
||||
'password_does_not_match':'The passwords you entered were not match.',
|
||||
},
|
||||
'ja_JP': {
|
||||
'drawer_title':'ロゲイニング参加者はログイン するとチェックポイントが参照 できます',
|
||||
@ -241,7 +243,7 @@ class StringValues extends Translations{
|
||||
'visit_history': '訪問履歴',
|
||||
'rog_web': 'ロゲイニングウェブサイト',
|
||||
'no_values': '値なし',
|
||||
'email_and_password_required': 'メールとパスワードが必要です',
|
||||
'email_and_password_required': 'メールとパスワードの入力が必要です',
|
||||
'rogaining_user_need_tosign_up': "ロゲイニング参加者はサインアップの必要はありません。",
|
||||
'add_location': '岐阜',
|
||||
'select_travel_mode':'移動モードを選択してください',
|
||||
@ -258,7 +260,7 @@ class StringValues extends Translations{
|
||||
'old_password' : '以前のパスワード',
|
||||
'new_password' : '新しいパスワード',
|
||||
'values_required' : '必要な値',
|
||||
'failed' : '失敗した',
|
||||
'failed' : '失敗',
|
||||
'password_change_failed_please_try_again' : 'パスワードの変更に失敗しました。もう一度お試しください',
|
||||
'user_registration_failed_please_try_again' : 'ユーザー登録に失敗しました。もう一度お試しください',
|
||||
'all': '全て',
|
||||
@ -424,6 +426,8 @@ class StringValues extends Translations{
|
||||
'reset_message': 'これにより、すべてのゲーム データが削除され、すべての状態が削除されます',
|
||||
'reset_done': 'リセット完了',
|
||||
'reset_explain': 'すべてリセットされました。ロゲ開始から再開して下さい。',
|
||||
'no_match': '不一致',
|
||||
'password_does_not_match':'入力したパスワードが一致しません',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user