Android release 4.8.2 revision 483

This commit is contained in:
2024-07-19 16:54:49 +09:00
parent 616f87c0c5
commit c81bcef4bc
10 changed files with 220 additions and 82 deletions

View File

@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dvox.gifunavi"> package="com.dvox.gifunavi">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="34" />
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

View File

@ -64,6 +64,7 @@ class LocationService : Service() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
Log.d("LocationService", "Android: onCreate.")
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
gpsDatabaseHelper = GpsDatabaseHelper.getInstance(applicationContext) gpsDatabaseHelper = GpsDatabaseHelper.getInstance(applicationContext)
@ -71,6 +72,8 @@ class LocationService : Service() {
// 位置情報の権限チェックとGPS有効化の確認を行う // 位置情報の権限チェックとGPS有効化の確認を行う
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE_LOCATION) == PackageManager.PERMISSION_GRANTED) { ContextCompat.checkSelfPermission(this, Manifest.permission.FOREGROUND_SERVICE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.d("LocationService", "Android: onCreate : 位置情報の権限チェックとGPS有効化の確認")
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
val locationRequest = LocationRequest.create().apply { val locationRequest = LocationRequest.create().apply {

View File

@ -52,12 +52,14 @@ class MainActivity: FlutterActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Log.d("MainActivity", "Android: onCreate.") Log.d("MainActivity", "Android: onCreate.")
// 位置情報の権限をリクエストする // 位置情報の権限をリクエストする==> main() の前にコールされるので除外 2024-7-19
/*
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_CODE) ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_REQUEST_CODE)
} else { } else {
// startLocationService() // アプリ起動時にLocationServiceを開始する ==> main.dartで制御する。 // startLocationService() // アプリ起動時にLocationServiceを開始する ==> main.dartで制御する。
} }
*/
} }

View File

@ -3,7 +3,7 @@ import 'dart:io';
//import 'dart:convert'; //import 'dart:convert';
//import 'dart:developer'; //import 'dart:developer';
import 'package:rogapp/model/gps_data.dart'; 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:rogapp/utils/database_gps.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.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 // startMemoryMonitoring(); // 2024-4-8 Akira: メモリ使用量のチェックを開始 See #2810
Get.put(SettingsController()); // これを追加 Get.put(SettingsController()); // これを追加
/* /*
runZonedGuarded(() { runZonedGuarded(() {
runApp(const ProviderScope(child: MyApp())); runApp(const ProviderScope(child: MyApp()));
@ -149,6 +150,8 @@ void main() async {
}); });
*/ */
runApp(const ProviderScope(child: MyApp())); runApp(const ProviderScope(child: MyApp()));
//runApp(HomePage()); // MyApp()からHomePage()に変更 //runApp(HomePage()); // MyApp()からHomePage()に変更
//runApp(const MyApp()); //runApp(const MyApp());
@ -324,7 +327,7 @@ Future<void> addGPStoDB(double la, double ln) async {
is_checkin: 0, is_checkin: 0,
created_at: DateTime.now().millisecondsSinceEpoch); created_at: DateTime.now().millisecondsSinceEpoch);
var res = await db.insertGps(gps_data); var res = await db.insertGps(gps_data);
//debugPrint("バックグラウンドでのGPS保存"); debugPrint("バックグラウンドでのGPS保存");
} catch (err) { } catch (err) {
print("errr ready gps ${err}"); print("errr ready gps ${err}");
return; return;
@ -367,52 +370,39 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
} }
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
// Add to clear // ウィジェットが構築された後に権限をチェック
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
showLocationDisclosure(context); PermissionController.checkAndRequestPermissions();
}); });
/*
WidgetsBinding.instance.addPostFrameCallback((_) async {
await PermissionController.checkAndRequestPermissions();
});
*/
debugPrint("Start MyAppState..."); debugPrint("Start MyAppState...");
} }
void showLocationDisclosure(BuildContext context) { /*
void showPermissionRequiredDialog() {
showDialog( showDialog(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text('位置情報の使用について'), title: Text('権限が必要です'),
content: const SingleChildScrollView( content: Text('このアプリは機能するために位置情報の権限が必要です。設定で権限を許可してください。'),
child: ListBody(
children: <Widget>[
Text('このアプリでは、以下の目的で位置情報を使用します:'),
Text('• チェックポイントの自動チェックイン(アプリが閉じているときも含む)'),
Text('• 移動履歴の記録(バックグラウンドでも継続)'),
Text('• 現在地周辺の情報表示'),
Text('\nバックグラウンドでも位置情報を継続的に取得します。'),
Text('これにより、バッテリーの消費が増加する可能性があります。'),
],
),
),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: const Text('同意しない'), child: Text('設定を開く'),
onPressed: () { onPressed: () {
openAppSettings();
Navigator.of(context).pop(); Navigator.of(context).pop();
// アプリを終了するなどの処理
}, },
), ),
TextButton( TextButton(
child: const Text('同意する'), child: Text('アプリを終了'),
onPressed: () { onPressed: () {
// アプリを終了
Navigator.of(context).pop(); 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 @override
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);

View File

@ -417,6 +417,7 @@ class IndexController extends GetxController with WidgetsBindingObserver {
void register(String email, String password, BuildContext context) { void register(String email, String password, BuildContext context) {
AuthService.register(email, password).then((value) { AuthService.register(email, password).then((value) {
if (value.isNotEmpty) { if (value.isNotEmpty) {
debugPrint("ユーザー登録成功:${email}, ${password}");
logManager.addOperationLog("User tried to register new account : ${email} , ${password} ."); logManager.addOperationLog("User tried to register new account : ${email} , ${password} .");
currentUser.clear(); currentUser.clear();
@ -425,16 +426,17 @@ class IndexController extends GetxController with WidgetsBindingObserver {
Navigator.pop(context); Navigator.pop(context);
Get.toNamed(AppPages.INDEX); Get.toNamed(AppPages.INDEX);
} else { } else {
debugPrint("ユーザー登録失敗:${email}, ${password}");
logManager.addOperationLog("User failed to register new account : ${email} , ${password} ."); logManager.addOperationLog("User failed to register new account : ${email} , ${password} .");
isLoading.value = false; isLoading.value = false;
Get.snackbar( Get.snackbar(
'failed'.tr, 'failed'.tr, // 失敗
'user_registration_failed_please_try_again'.tr, 'user_registration_failed_please_try_again'.tr, // ユーザー登録に失敗しました。
backgroundColor: Colors.red, backgroundColor: Colors.red,
colorText: Colors.white, colorText: Colors.white,
icon: const Icon(Icons.error, size: 40.0, color: Colors.blue), icon: const Icon(Icons.error, size: 40.0, color: Colors.blue),
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
duration: const Duration(milliseconds: 800), duration: const Duration(seconds: 3),
//backgroundColor: Colors.yellow, //backgroundColor: Colors.yellow,
//icon:Image(image:AssetImage("assets/images/dora.png")) //icon:Image(image:AssetImage("assets/images/dora.png"))
); );

View File

@ -4,21 +4,174 @@ import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:rogapp/services/location_service.dart'; import 'package:rogapp/services/location_service.dart';
import 'dart:developer' as developer; import 'dart:developer' as developer;
import 'dart:async';
class PermissionController { class PermissionController {
/* static bool _isRequestingPermission = false;
static Future<bool> checkLocationPermissions() async { static Completer<bool>? _permissionCompleter;
debugPrint("(gifunavi)== checkLocationPermissions ==");
final alwaysPermission = await Permission.locationAlways.status;
final whenInUsePermission = await Permission.locationWhenInUse.status;
final locationPermission = await Permission.location.status;
return (alwaysPermission == PermissionStatus.granted || whenInUsePermission == PermissionStatus.granted) && static Future<bool> checkLocationPermissions() async {
(locationPermission == PermissionStatus.granted); 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 { static Future<bool> checkStoragePermission() async {
//debugPrint("(gifunavi)== checkStoragePermission =="); //debugPrint("(gifunavi)== checkStoragePermission ==");
@ -42,6 +195,7 @@ class PermissionController {
} }
/*
static Future<bool> checkLocationBasicPermission() async { static Future<bool> checkLocationBasicPermission() async {
//debugPrint("(gifunavi)== checkLocationBasicPermission =="); //debugPrint("(gifunavi)== checkLocationBasicPermission ==");
final locationPermission = await Permission.location.status; 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();
},
),
],
),
);
}
} }

View File

@ -44,8 +44,8 @@ class RegisterPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
Text( Text(
"sign_up".tr, "sign_up".tr, // "サインアップ"
style: TextStyle( style: const TextStyle(
fontSize: 30, fontSize: 30,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
@ -54,7 +54,7 @@ class RegisterPage extends StatelessWidget {
height: 20, height: 20,
), ),
Text( Text(
"create_account".tr, "create_account".tr, // アカウントを無料で作成します。
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
color: Colors.grey[700], color: Colors.grey[700],
@ -69,15 +69,15 @@ class RegisterPage extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 40), padding: const EdgeInsets.symmetric(horizontal: 40),
child: Column( child: Column(
children: [ children: [
makeInput(label: "email".tr, controller: emailController), makeInput(label: "email".tr, controller: emailController), // メールアドレス
makeInput( makeInput(
label: "password".tr, label: "password".tr,
controller: passwordController, controller: passwordController,
obsureText: true), obsureText: true), // パスワード
makeInput( makeInput(
label: "confirm_password".tr, label: "confirm_password".tr,
controller: confirmPasswordController, controller: confirmPasswordController,
obsureText: true) obsureText: true) // パスワード再確認
], ],
), ),
), ),
@ -99,14 +99,14 @@ class RegisterPage extends StatelessWidget {
if (passwordController.text != if (passwordController.text !=
confirmPasswordController.text) { confirmPasswordController.text) {
Get.snackbar( Get.snackbar(
"No match", "no_match".tr,
"Passwords does not match", "password_does_not_match".tr,
backgroundColor: Colors.red, backgroundColor: Colors.red,
colorText: Colors.white, colorText: Colors.white,
icon: const Icon(Icons.assistant_photo_outlined, icon: const Icon(Icons.assistant_photo_outlined,
size: 40.0, color: Colors.blue), size: 40.0, color: Colors.blue),
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
duration: const Duration(milliseconds: 800), duration: const Duration(seconds: 3),
// backgroundColor: Colors.yellow, // backgroundColor: Colors.yellow,
//icon:Image(image:AssetImage("assets/images/dora.png")) //icon:Image(image:AssetImage("assets/images/dora.png"))
); );
@ -121,7 +121,7 @@ class RegisterPage extends StatelessWidget {
icon: const Icon(Icons.assistant_photo_outlined, icon: const Icon(Icons.assistant_photo_outlined,
size: 40.0, color: Colors.blue), size: 40.0, color: Colors.blue),
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
duration: const Duration(milliseconds: 800), duration: const Duration(seconds: 3),
//backgroundColor: Colors.yellow, //backgroundColor: Colors.yellow,
//icon:Image(image:AssetImage("assets/images/dora.png")) //icon:Image(image:AssetImage("assets/images/dora.png"))
); );

View File

@ -129,12 +129,14 @@ class AuthService {
return cats; return cats;
} }
// ユーザー登録
//
static Future<Map<String, dynamic>> register( static Future<Map<String, dynamic>> register(
String email, String password) async { String email, String password) async {
Map<String, dynamic> cats = {}; Map<String, dynamic> cats = {};
String serverUrl = ConstValues.currentServer(); String serverUrl = ConstValues.currentServer();
String url = '$serverUrl/api/register/'; String url = '$serverUrl/api/register/';
//print('++++++++$url'); debugPrint('++++++++${url}');
final http.Response response = await http.post( final http.Response response = await http.post(
Uri.parse(url), Uri.parse(url),
headers: <String, String>{ headers: <String, String>{

View File

@ -30,7 +30,7 @@ class StringValues extends Translations{
'visit_history': 'Visit History', 'visit_history': 'Visit History',
'rog_web': 'rog website', 'rog_web': 'rog website',
'no_values': 'No Values', '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.", 'rogaining_user_need_tosign_up': "Rogaining participants do need to sign up.",
'add_location': 'Gifu', 'add_location': 'Gifu',
'select_travel_mode':'Select your travel mode', '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_message': 'Are you ok to reset all data in this device?',
'reset_done': 'Reset Done.', 'reset_done': 'Reset Done.',
'reset_explain': 'All data has been reset. You should tap start rogaining to start game.', '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': { 'ja_JP': {
'drawer_title':'ロゲイニング参加者はログイン するとチェックポイントが参照 できます', 'drawer_title':'ロゲイニング参加者はログイン するとチェックポイントが参照 できます',
@ -241,7 +243,7 @@ class StringValues extends Translations{
'visit_history': '訪問履歴', 'visit_history': '訪問履歴',
'rog_web': 'ロゲイニングウェブサイト', 'rog_web': 'ロゲイニングウェブサイト',
'no_values': '値なし', 'no_values': '値なし',
'email_and_password_required': 'メールとパスワードが必要です', 'email_and_password_required': 'メールとパスワードの入力が必要です',
'rogaining_user_need_tosign_up': "ロゲイニング参加者はサインアップの必要はありません。", 'rogaining_user_need_tosign_up': "ロゲイニング参加者はサインアップの必要はありません。",
'add_location': '岐阜', 'add_location': '岐阜',
'select_travel_mode':'移動モードを選択してください', 'select_travel_mode':'移動モードを選択してください',
@ -258,7 +260,7 @@ class StringValues extends Translations{
'old_password' : '以前のパスワード', 'old_password' : '以前のパスワード',
'new_password' : '新しいパスワード', 'new_password' : '新しいパスワード',
'values_required' : '必要な値', 'values_required' : '必要な値',
'failed' : '失敗した', 'failed' : '失敗',
'password_change_failed_please_try_again' : 'パスワードの変更に失敗しました。もう一度お試しください', 'password_change_failed_please_try_again' : 'パスワードの変更に失敗しました。もう一度お試しください',
'user_registration_failed_please_try_again' : 'ユーザー登録に失敗しました。もう一度お試しください', 'user_registration_failed_please_try_again' : 'ユーザー登録に失敗しました。もう一度お試しください',
'all': '全て', 'all': '全て',
@ -424,6 +426,8 @@ class StringValues extends Translations{
'reset_message': 'これにより、すべてのゲーム データが削除され、すべての状態が削除されます', 'reset_message': 'これにより、すべてのゲーム データが削除され、すべての状態が削除されます',
'reset_done': 'リセット完了', 'reset_done': 'リセット完了',
'reset_explain': 'すべてリセットされました。ロゲ開始から再開して下さい。', 'reset_explain': 'すべてリセットされました。ロゲ開始から再開して下さい。',
'no_match': '不一致',
'password_does_not_match':'入力したパスワードが一致しません',
}, },
}; };
} }

View File

@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 4.8.1+481 version: 4.8.2+483
environment: environment:
sdk: ">=3.2.0 <4.0.0" sdk: ">=3.2.0 <4.0.0"