Fixed Location Permission issue on Android - 1

This commit is contained in:
2024-05-24 07:21:28 +09:00
parent 74f6a79a36
commit e55674e1b9
19 changed files with 376 additions and 330 deletions

View File

@ -1,78 +1,156 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:rogapp/routes/app_pages.dart';
import 'package:rogapp/services/location_service.dart';
import 'dart:developer' as developer;
class PermissionHandlerScreen extends StatefulWidget {
const PermissionHandlerScreen({Key? key}) : super(key: key);
@override
_PermissionHandlerScreenState createState() =>
_PermissionHandlerScreenState();
}
class PermissionController {
class _PermissionHandlerScreenState extends State<PermissionHandlerScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_checkPermissionStatus();
});
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;
return (alwaysPermission == PermissionStatus.granted || whenInUsePermission == PermissionStatus.granted) &&
(locationPermission == PermissionStatus.granted);
}
Future<void> _checkPermissionStatus() async {
PermissionStatus status = await Permission.location.status;
static Future<bool> checkLocationBasicPermission() async {
debugPrint("(gifunavi)== checkLocationBasicPermission ==");
final locationPermission = await Permission.location.status;
return locationPermission == PermissionStatus.granted;
}
if (status.isGranted) {
if (context.mounted) {
Get.offNamed(AppPages.LOGIN);
static Future<bool> checkLocationWhenInUsePermission() async {
debugPrint("(gifunavi)== checkLocationWhenInUsePermission ==");
final whenInUsePermission = await Permission.locationWhenInUse.status;
return whenInUsePermission == PermissionStatus.granted;
}
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();
}
}
} else {
if (context.mounted) {
_showPermissionRequestDialog();
}catch (e, stackTrace){
print('Exception: $e');
print('Stack trace: $stackTrace');
debugPrintStack(label: 'Exception occurred', stackTrace: stackTrace);
}
}
static bool isLocationServiceRunning = false;
static bool isRequestedWhenInUsePermission = false;
static Future<void> requestLocationWhenInUsePermissions() async {
debugPrint("(gifunavi)== requestLocationWhenInUsePermissions ==");
try{
if(!isRequestedWhenInUsePermission){
isRequestedWhenInUsePermission=true;
final whenInUseStatus = await Permission.locationWhenInUse.request();
if (whenInUseStatus != PermissionStatus.granted) {
showPermissionDeniedDialog();
}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}'.");
}
}
}
}
}catch (e, stackTrace){
debugPrint('Exception: $e');
debugPrint('Stack trace: $stackTrace');
debugPrintStack(label: 'Exception occurred', stackTrace: stackTrace);
}
}
static bool isRequestedAlwaysPermission = false;
static Future<void> requestLocationAlwaysPermissions() async {
debugPrint("(gifunavi)== requestLocationAlwaysPermissions ==");
try {
if( !isRequestedAlwaysPermission ){
isRequestedAlwaysPermission=true;
final alwaysStatus = await Permission.locationAlways.request();
if (alwaysStatus != PermissionStatus.granted) {
showPermissionDeniedDialog();
}
}
}catch (e, stackTrace){
print('Exception: $e');
print('Stack trace: $stackTrace');
debugPrintStack(label: 'Exception occurred', stackTrace: stackTrace);
}
}
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();
}
}
void _showPermissionRequestDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('location_permission_required_title'.tr),
content: Text('location_permission_required_message'.tr),
actions: [
TextButton(
child: Text('cancel'.tr),
onPressed: () {
Navigator.of(context).pop();
Get.offNamed(AppPages.HOME);
},
),
TextButton(
child: Text('ok'.tr),
onPressed: () {
Navigator.of(context).pop();
_requestLocationPermission();
},
),
],
);
},
static void showPermissionDeniedDialog() {
Get.dialog(
AlertDialog(
title: Text('location_permission_needed_title'.tr),
// 位置情報への許可が必要です
content: Text('location_permission_needed_main'.tr),
// 岐阜ロゲでは、位置情報を使用してスタート・チェックイン・ゴール等の通過照明及び移動手段の記録のために、位置情報のトラッキングを行なっています。このためバックグラウンドでもトラッキングができるように位置情報の権限が必要です。
// 設定画面で、「岐阜ナビ」に対して、常に位置情報を許可するように設定してください。
actions: [
TextButton(
child: Text('キャンセル'),
onPressed: () => Get.back(),
),
TextButton(
child: Text('設定'),
onPressed: () {
Get.back();
openAppSettings();
},
),
],
),
);
}
void _requestLocationPermission() async {
final status = await Permission.location.request();
if (status.isGranted) {
Get.offNamed(AppPages.LOGIN);
} else {
Get.offNamed(AppPages.HOME);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(body: Container());
}
}

View File

@ -1,188 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:rogapp/routes/app_pages.dart';
import 'dart:io';
class PermissionHandlerScreen extends StatefulWidget {
const PermissionHandlerScreen({Key? key}) : super(key: key);
@override
State<PermissionHandlerScreen> createState() =>
_PermissionHandlerScreenState();
}
class _PermissionHandlerScreenState extends State<PermissionHandlerScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_checkPermissionStatus();
});
}
Future<void> _checkPermissionStatus() async {
PermissionStatus status = await Permission.location.status;
if (status.isGranted) {
if (context.mounted) {
Get.toNamed(AppPages.LOGIN);
}
} else {
if (context.mounted) {
Get.toNamed(AppPages.HOME);
}
}
}
/*
_checkPermissionStatus() async {
PermissionStatus status = await Permission.location.status;
if (status.isGranted == false) {
if (context.mounted) {
showAlert(context);
}
} else if (status.isPermanentlyDenied) {
await requestPermission();
} else {
if (mounted) {
Get.toNamed(AppPages.LOGIN);
}
}
}
*/
void showAlert(BuildContext context) {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('location_permission_title'.tr),
content: SingleChildScrollView(
child: Text('location_permission_content'.tr),
),
actions: <Widget>[
ElevatedButton(
child: const Text('OK'),
onPressed: () {
Get.back();
requestPermission();
},
),
],
));
}
// 要検討:位置情報の許可が拒否された場合、適切なエラーメッセージを表示することを検討してください。
//
/*
Future<void> requestPermission() async {
PermissionStatus permission = await Permission.location.status;
if (permission == PermissionStatus.permanentlyDenied) {
showPermanentAlert();
} else {
PermissionStatus newPermission = await Permission.location.request();
if (newPermission != PermissionStatus.granted) {
exit(0);
} else {
if (context.mounted) {
Get.toNamed(AppPages.LOGIN);
}
}
}
}
*/
Future<void> requestPermission() async {
PermissionStatus permission = await Permission.location.request();
if (permission == PermissionStatus.granted) {
if (context.mounted) {
Get.toNamed(AppPages.LOGIN);
}
} else if (permission == PermissionStatus.denied) {
await showLocationPermissionDeniedDialog();
} else if (permission == PermissionStatus.permanentlyDenied) {
await showPermanentlyDeniedDialog();
}
}
Future<void> showLocationPermissionDeniedDialog() async {
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('location_permission_denied_title'.tr),
content: Text('location_permission_denied_message'.tr),
actions: [
TextButton(
child: Text('ok'.tr),
onPressed: () => Navigator.of(context).pop(),
),
],
);
},
);
}
Future<void> showPermanentlyDeniedDialog() async {
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('location_permission_permanently_denied_title'.tr),
content: Text('location_permission_permanently_denied_message'.tr),
actions: [
TextButton(
child: Text('open_settings'.tr),
onPressed: () {
Navigator.of(context).pop();
openAppSettings();
},
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Text(""),
);
}
// 要検討:ユーザーが位置情報の許可を拒否し続けた場合の対処方法を明確にすることをお勧めします。
//
void showPermanentAlert() {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('location_disabled_title'.tr),
content: SingleChildScrollView(
child: Text('location_disabled_content'.tr),
),
actions: <Widget>[
ElevatedButton(
child: const Text('OK'),
onPressed: () async {
await openAppSettings().then(
(value) async {
if (value) {
if (await Permission
.location.status.isPermanentlyDenied ==
true &&
await Permission.location.status.isGranted ==
false) {
requestPermission(); /* opens app settings until permission is granted */
}
}
},
);
},
),
],
));
}
}