fix: permission screen location request - request WhenInUse first then Always

This commit is contained in:
fiatcode 2026-04-30 16:33:38 +07:00
parent 93d5534755
commit 4f16db59b2
No known key found for this signature in database

View file

@ -56,32 +56,54 @@ class _PermissionScreenState extends State<PermissionScreen> {
_locationGranted && _notificationGranted && _batteryOptOut;
Future<void> _requestLocation() async {
final status = await Permission.locationAlways.request();
// Check current status first
var status = await Permission.locationAlways.status;
if (status.isGranted) {
if (mounted) setState(() => _locationGranted = true);
return;
}
// On Android, request locationWhenInUse first before locationAlways
var whenInUse = await Permission.locationWhenInUse.status;
if (!whenInUse.isGranted) {
whenInUse = await Permission.locationWhenInUse.request();
}
// Now request locationAlways (background permission)
status = await Permission.locationAlways.request();
if (!status.isGranted && status.isPermanentlyDenied) {
// Permission permanently denied - open app settings
await openAppSettings();
}
final finalStatus = await Permission.locationAlways.status;
if (mounted) {
final newStatus = await Permission.locationAlways.status;
setState(() => _locationGranted = newStatus.isGranted);
setState(() => _locationGranted = finalStatus.isGranted);
}
}
Future<void> _requestNotification() async {
final status = await Permission.notification.request();
var status = await Permission.notification.status;
if (status.isGranted) {
if (mounted) setState(() => _notificationGranted = true);
return;
}
status = await Permission.notification.request();
if (!status.isGranted && status.isPermanentlyDenied) {
await openAppSettings();
}
final finalStatus = await Permission.notification.status;
if (mounted) {
final newStatus = await Permission.notification.status;
setState(() => _notificationGranted = newStatus.isGranted);
setState(() => _notificationGranted = finalStatus.isGranted);
}
}
Future<void> _requestBatteryOptOut() async {
final opened = await LocationBridge.openBatteryOptimizationSettings();
if (mounted) {
// Show dialog after the settings screen opens
_showBatteryOptDialog(opened);
}
}
@ -109,8 +131,8 @@ class _PermissionScreenState extends State<PermissionScreen> {
content: Text(
settingsOpened
? 'A settings screen has opened.\n\n'
'Find "Traccar Client" and set it to "Don\'t optimize" or "Unrestricted", then come back and tap DONE below.'
: 'Open Settings → Apps → Traccar Client → Battery and select "Don\'t optimize" or "Unrestricted", then come back and tap DONE below.',
'Find "Traccar Client" and set it to "Don\'t optimize" or "Unrestricted", then come back and tap CHECK & DONE.'
: 'Open Settings → Apps → Traccar Client → Battery and select "Don\'t optimize" or "Unrestricted", then come back and tap CHECK & DONE.',
style: const TextStyle(
fontFamily: 'monospace',
fontSize: 12,
@ -121,7 +143,6 @@ class _PermissionScreenState extends State<PermissionScreen> {
TextButton(
onPressed: () {
Navigator.pop(ctx);
// Open app details settings as fallback
openAppSettings();
},
child: const Text(
@ -138,7 +159,6 @@ class _PermissionScreenState extends State<PermissionScreen> {
TextButton(
onPressed: () async {
Navigator.pop(ctx);
// Re-check battery optimization state via native
final disabled = await _isBatteryOptimizationDisabled();
if (mounted) {
setState(() => _batteryOptOut = disabled);
@ -273,8 +293,8 @@ class _PermissionScreenState extends State<PermissionScreen> {
size: 20,
),
),
SizedBox(width: 14),
Expanded(
const SizedBox(width: 14),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [