2024-09-02 ほぼOK
This commit is contained in:
@ -1,3 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:get/get.dart';
|
||||
@ -10,15 +12,6 @@ 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;
|
||||
@ -27,13 +20,119 @@ class PermissionController {
|
||||
_isRequestingPermission = true;
|
||||
_permissionCompleter = Completer<bool>();
|
||||
|
||||
bool hasPermissions = await checkLocationPermissions();
|
||||
try {
|
||||
bool hasPermissions = await _checkLocationPermissions();
|
||||
if (!hasPermissions) {
|
||||
bool userAgreed = await showLocationDisclosure();
|
||||
if (userAgreed) {
|
||||
if (Platform.isAndroid && !await _isAndroid13OrAbove()) {
|
||||
hasPermissions = await _requestAndroidPreS();
|
||||
} else {
|
||||
hasPermissions = await _requestAllLocationPermissions();
|
||||
}
|
||||
} else {
|
||||
print('User did not agree to location usage');
|
||||
hasPermissions = false;
|
||||
SystemNavigator.pop();
|
||||
}
|
||||
}
|
||||
|
||||
_isRequestingPermission = false;
|
||||
_permissionCompleter!.complete(hasPermissions);
|
||||
} catch (e) {
|
||||
print('Error in permission request: $e');
|
||||
_isRequestingPermission = false;
|
||||
_permissionCompleter!.complete(false);
|
||||
}
|
||||
|
||||
return _permissionCompleter!.future;
|
||||
}
|
||||
|
||||
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> _requestAllLocationPermissions() async {
|
||||
await Permission.location.request();
|
||||
await Permission.locationWhenInUse.request();
|
||||
final alwaysStatus = await Permission.locationAlways.request();
|
||||
|
||||
return alwaysStatus == PermissionStatus.granted;
|
||||
}
|
||||
|
||||
static Future<bool> _requestAndroidPreS() async {
|
||||
await Permission.location.request();
|
||||
await Permission.locationWhenInUse.request();
|
||||
|
||||
// Android 13以前では、ユーザーに設定画面で権限を許可するように促す
|
||||
await showDialog(
|
||||
context: Get.context!,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text('バックグラウンド位置情報の許可'),
|
||||
content: Text('アプリの設定画面で「常に許可」を選択してください。'),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text('設定を開く'),
|
||||
onPressed: () {
|
||||
openAppSettings();
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
// 設定画面から戻ってきた後、再度権限をチェック
|
||||
return await Permission.locationAlways.isGranted;
|
||||
}
|
||||
|
||||
static Future<bool> _isAndroid13OrAbove() async {
|
||||
if (Platform.isAndroid) {
|
||||
final androidVersion = int.tryParse(Platform.operatingSystemVersion.split('.').first) ?? 0;
|
||||
return androidVersion >= 13;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static Future<bool> checkLocationPermissions_old() async {
|
||||
final locationPermission = await Permission.location.status;
|
||||
if (locationPermission.isDenied) {
|
||||
await showLocationDisclosure();
|
||||
final result = await Permission.location.request();
|
||||
if (result.isDenied) {
|
||||
await openAppSettings();
|
||||
}
|
||||
}
|
||||
|
||||
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_old() 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();
|
||||
hasPermissions = await _checkLocationPermissions();
|
||||
} catch (e) {
|
||||
print('Error requesting location permissions: $e');
|
||||
hasPermissions = false;
|
||||
@ -48,6 +147,8 @@ class PermissionController {
|
||||
|
||||
_isRequestingPermission = false;
|
||||
_permissionCompleter!.complete(hasPermissions);
|
||||
|
||||
debugPrint("Finish checkAndRequestPermissions...");
|
||||
return _permissionCompleter!.future;
|
||||
}
|
||||
|
||||
@ -67,35 +168,51 @@ class PermissionController {
|
||||
}
|
||||
|
||||
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('同意しない場合には、アプリは終了します。'),
|
||||
],
|
||||
if (Get.context == null) {
|
||||
print('Context is null, cannot show dialog');
|
||||
return false;
|
||||
}
|
||||
if (Get.isDialogOpen ?? false) {
|
||||
print('A dialog is already open');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
final result = await Get.dialog<bool>(
|
||||
AlertDialog(
|
||||
title: const 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),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: const Text('同意しない'),
|
||||
onPressed: () => Get.back(result: false),
|
||||
),
|
||||
TextButton(
|
||||
child: const Text('同意する'),
|
||||
onPressed: () => Get.back(result: true),
|
||||
),
|
||||
],
|
||||
),
|
||||
barrierDismissible: false,
|
||||
) ?? false;
|
||||
barrierDismissible: false,
|
||||
);
|
||||
return result ?? false;
|
||||
}catch(e){
|
||||
print('Dialog error: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void showPermissionDeniedDialog(String title,String message) {
|
||||
|
||||
Reference in New Issue
Block a user