2022-07-20 15:57:40 +05:30
|
|
|
|
import 'package:flutter/material.dart';
|
2024-08-22 14:35:09 +09:00
|
|
|
|
import 'package:flutter/services.dart';
|
2022-07-20 15:57:40 +05:30
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
|
|
import 'package:permission_handler/permission_handler.dart';
|
2024-08-22 14:35:09 +09:00
|
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PermissionController {
|
|
|
|
|
|
|
|
|
|
|
|
static bool _isRequestingPermission = false;
|
|
|
|
|
|
static Completer<bool>? _permissionCompleter;
|
|
|
|
|
|
|
|
|
|
|
|
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: const Text('位置情報の使用について'),
|
|
|
|
|
|
content: const SingleChildScrollView(
|
|
|
|
|
|
child: ListBody(
|
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
|
Text('このアプリでは、以下の目的で位置情報を使用します:'),
|
|
|
|
|
|
Text('• チェックポイントの自動チェックイン(アプリが閉じているときも含む)'),
|
|
|
|
|
|
Text('• 移動履歴の記録(バックグラウンドでも継続)'),
|
|
|
|
|
|
Text('• 現在地周辺の情報表示'),
|
|
|
|
|
|
Text('\nバックグラウンドでも位置情報を継続的に取得します。'),
|
|
|
|
|
|
Text('これにより、バッテリーの消費が増加する可能性があります。'),
|
|
|
|
|
|
Text('同意しない場合には、アプリは終了します。'),
|
|
|
|
|
|
],
|
2022-12-22 14:06:02 +05:30
|
|
|
|
),
|
2024-08-22 14:35:09 +09:00
|
|
|
|
),
|
|
|
|
|
|
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: const Text('キャンセル'),
|
|
|
|
|
|
onPressed: () => Get.back(),
|
|
|
|
|
|
),
|
|
|
|
|
|
TextButton(
|
|
|
|
|
|
child: const Text('設定'),
|
|
|
|
|
|
onPressed: () {
|
|
|
|
|
|
Get.back();
|
|
|
|
|
|
openAppSettings();
|
|
|
|
|
|
},
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
2022-12-22 14:06:02 +05:30
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
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 ==");
|
|
|
|
|
|
final storagePermission = await Permission.storage.status;
|
|
|
|
|
|
return storagePermission == PermissionStatus.granted;
|
2023-01-19 16:39:25 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static Future<void> requestStoragePermission() async {
|
|
|
|
|
|
//debugPrint("(gifunavi)== requestStoragePermission ==");
|
|
|
|
|
|
final storagePermission = await Permission.storage.request();
|
|
|
|
|
|
|
|
|
|
|
|
if (storagePermission == PermissionStatus.granted) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (storagePermission == PermissionStatus.permanentlyDenied) {
|
|
|
|
|
|
// リクエストが完了するまで待機
|
|
|
|
|
|
await Future.delayed(const Duration(milliseconds: 500));
|
|
|
|
|
|
showPermissionDeniedDialog('storage_permission_needed_title','storage_permission_needed_main');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
/*
|
|
|
|
|
|
static Future<bool> checkLocationBasicPermission() async {
|
|
|
|
|
|
//debugPrint("(gifunavi)== checkLocationBasicPermission ==");
|
|
|
|
|
|
final locationPermission = await Permission.location.status;
|
|
|
|
|
|
return locationPermission == PermissionStatus.granted;
|
|
|
|
|
|
}
|
2022-07-20 15:57:40 +05:30
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static Future<bool> checkLocationWhenInUsePermission() async {
|
|
|
|
|
|
//debugPrint("(gifunavi)== checkLocationWhenInUsePermission ==");
|
|
|
|
|
|
final whenInUsePermission = await Permission.locationWhenInUse.status;
|
|
|
|
|
|
return whenInUsePermission == PermissionStatus.granted;
|
|
|
|
|
|
}
|
2022-07-20 15:57:40 +05:30
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static Future<bool> checkLocationAlwaysPermission() async {
|
|
|
|
|
|
//debugPrint("(gifunavi)== checkLocationAlwaysPermission ==");
|
|
|
|
|
|
final alwaysPermission = await Permission.locationAlways.status;
|
|
|
|
|
|
return alwaysPermission == PermissionStatus.granted;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool isBasicPermission=false;
|
|
|
|
|
|
static Future<void> requestLocationBasicPermissions() async {
|
|
|
|
|
|
//debugPrint("(gifunavi)== requestLocationBasicPermissions ==");
|
|
|
|
|
|
try{
|
|
|
|
|
|
if(!isBasicPermission){
|
|
|
|
|
|
isBasicPermission=true;
|
|
|
|
|
|
final locationStatus = await Permission.location.request();
|
|
|
|
|
|
|
|
|
|
|
|
if (locationStatus != PermissionStatus.granted) {
|
|
|
|
|
|
showPermissionDeniedDialog('location_permission_needed_title','location_permission_needed_main');
|
2023-09-03 23:37:41 +05:30
|
|
|
|
}
|
2024-08-22 14:35:09 +09:00
|
|
|
|
}
|
|
|
|
|
|
}catch (e, stackTrace){
|
|
|
|
|
|
print('Exception: $e');
|
|
|
|
|
|
print('Stack trace: $stackTrace');
|
|
|
|
|
|
debugPrintStack(label: 'Exception occurred', stackTrace: stackTrace);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static bool isLocationServiceRunning = false;
|
|
|
|
|
|
static bool isRequestedWhenInUsePermission = false;
|
2022-07-20 15:57:40 +05:30
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static Future<void> requestLocationWhenInUsePermissions() async {
|
|
|
|
|
|
//debugPrint("(gifunavi)== requestLocationWhenInUsePermissions ==");
|
|
|
|
|
|
|
|
|
|
|
|
try{
|
|
|
|
|
|
if(!isRequestedWhenInUsePermission){
|
|
|
|
|
|
isRequestedWhenInUsePermission=true;
|
|
|
|
|
|
final whenInUseStatus = await Permission.locationWhenInUse.request();
|
|
|
|
|
|
|
|
|
|
|
|
if (whenInUseStatus != PermissionStatus.granted) {
|
|
|
|
|
|
showPermissionDeniedDialog('location_permission_needed_title','location_permission_needed_main');
|
|
|
|
|
|
}else{
|
|
|
|
|
|
if( !isLocationServiceRunning ){
|
|
|
|
|
|
isLocationServiceRunning=true;
|
|
|
|
|
|
const platform = MethodChannel('location');
|
|
|
|
|
|
try {
|
|
|
|
|
|
await platform.invokeMethod('startLocationService'); // Location Service を開始する。
|
|
|
|
|
|
} on PlatformException catch (e) {
|
|
|
|
|
|
debugPrint("Failed to start location service: '${e.message}'.");
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-08-22 14:35:09 +09:00
|
|
|
|
}
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|
2024-08-22 14:35:09 +09:00
|
|
|
|
}catch (e, stackTrace){
|
|
|
|
|
|
debugPrint('Exception: $e');
|
|
|
|
|
|
debugPrint('Stack trace: $stackTrace');
|
|
|
|
|
|
debugPrintStack(label: 'Exception occurred', stackTrace: stackTrace);
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|
2024-08-22 14:35:09 +09:00
|
|
|
|
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static bool isRequestedAlwaysPermission = false;
|
2022-07-20 15:57:40 +05:30
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static Future<void> requestLocationAlwaysPermissions() async {
|
|
|
|
|
|
//debugPrint("(gifunavi)== requestLocationAlwaysPermissions ==");
|
2022-07-20 15:57:40 +05:30
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
try {
|
|
|
|
|
|
if( !isRequestedAlwaysPermission ){
|
|
|
|
|
|
isRequestedAlwaysPermission=true;
|
|
|
|
|
|
final alwaysStatus = await Permission.locationAlways.request();
|
|
|
|
|
|
|
|
|
|
|
|
if (alwaysStatus != PermissionStatus.granted) {
|
|
|
|
|
|
showPermissionDeniedDialog('location_permission_needed_title','location_permission_needed_main');
|
|
|
|
|
|
}
|
2023-01-19 16:39:25 +05:30
|
|
|
|
}
|
2024-08-22 14:35:09 +09:00
|
|
|
|
}catch (e, stackTrace){
|
|
|
|
|
|
print('Exception: $e');
|
|
|
|
|
|
print('Stack trace: $stackTrace');
|
|
|
|
|
|
debugPrintStack(label: 'Exception occurred', stackTrace: stackTrace);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-19 16:39:25 +05:30
|
|
|
|
}
|
|
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
static Future<void> checkAndRequestPermissions() async {
|
|
|
|
|
|
final hasPermissions = await checkLocationBasicPermission();
|
|
|
|
|
|
if (!hasPermissions) {
|
|
|
|
|
|
await requestLocationBasicPermissions();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
final hasWIUPermissions = await checkLocationWhenInUsePermission();
|
|
|
|
|
|
if (!hasWIUPermissions) {
|
|
|
|
|
|
await requestLocationWhenInUsePermissions();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
final hasAlwaysPermissions = await checkLocationAlwaysPermission();
|
|
|
|
|
|
if (!hasAlwaysPermissions) {
|
|
|
|
|
|
await requestLocationAlwaysPermissions();
|
|
|
|
|
|
}
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|
2023-01-19 16:39:25 +05:30
|
|
|
|
|
|
|
|
|
|
|
2024-08-22 14:35:09 +09:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-07-20 15:57:40 +05:30
|
|
|
|
}
|