From 3e8ba9a603e73ea5d64319de778a923bb514e79b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 4 Nov 2021 19:18:09 -0700 Subject: [PATCH] Fix Android 11 location permissions --- app/src/main/AndroidManifest.xml | 1 + .../client/BatteryOptimizationHelper.kt | 8 +++- .../java/org/traccar/client/MainFragment.kt | 38 ++++++++++++++++--- app/src/main/res/values/strings.xml | 2 + 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7498f5a..0b39d81 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + diff --git a/app/src/main/java/org/traccar/client/BatteryOptimizationHelper.kt b/app/src/main/java/org/traccar/client/BatteryOptimizationHelper.kt index f3bf9e5..cdaf8c0 100644 --- a/app/src/main/java/org/traccar/client/BatteryOptimizationHelper.kt +++ b/app/src/main/java/org/traccar/client/BatteryOptimizationHelper.kt @@ -66,7 +66,7 @@ class BatteryOptimizationHelper { } } - fun requestException(context: Context) { + fun requestException(context: Context): Boolean { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) if (!sharedPreferences.getBoolean(KEY_EXCEPTION_REQUESTED, false)) { @@ -80,15 +80,19 @@ class BatteryOptimizationHelper { requestVendorException(context) } } + return true } } else if (!sharedPreferences.getBoolean(KEY_AUTOSTART_REQUESTED, false)) { sharedPreferences.edit().putBoolean(KEY_AUTOSTART_REQUESTED, true).apply() try { - AutoStartPermissionHelper.getInstance().getAutoStartPermission(context) + if (AutoStartPermissionHelper.getInstance().getAutoStartPermission(context)) { + return true + } } catch (e: SecurityException) { } } } + return false } companion object { diff --git a/app/src/main/java/org/traccar/client/MainFragment.kt b/app/src/main/java/org/traccar/client/MainFragment.kt index 7cefcd5..2944392 100644 --- a/app/src/main/java/org/traccar/client/MainFragment.kt +++ b/app/src/main/java/org/traccar/client/MainFragment.kt @@ -54,6 +54,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene private lateinit var sharedPreferences: SharedPreferences private lateinit var alarmManager: AlarmManager private lateinit var alarmIntent: PendingIntent + private var requestingPermissions: Boolean = false @SuppressLint("UnspecifiedImmutableFlag") override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { @@ -154,6 +155,13 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene } } + override fun onStart() { + super.onStart() + if (requestingPermissions) { + requestingPermissions = BatteryOptimizationHelper().requestException(requireContext()) + } + } + override fun onResume() { super.onResume() sharedPreferences.registerOnSharedPreferenceChangeListener(this) @@ -214,6 +222,19 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene findPreference(KEY_DEVICE)?.summary = sharedPreferences.getString(KEY_DEVICE, null) } + private fun showBackgroundLocationDialog(context: Context, onSuccess: () -> Unit) { + val builder = AlertDialog.Builder(context) + val option = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + context.packageManager.backgroundPermissionOptionLabel + } else { + context.getString(R.string.request_background_option) + } + builder.setMessage(context.getString(R.string.request_background, option)) + builder.setPositiveButton(android.R.string.ok) { _, _ -> onSuccess() } + builder.setNegativeButton(android.R.string.cancel, null) + builder.show() + } + private fun startTrackingService(checkPermission: Boolean, initialPermission: Boolean) { var permission = initialPermission if (checkPermission) { @@ -224,10 +245,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene permission = requiredPermissions.isEmpty() if (!permission) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestPermissions( - requiredPermissions.toTypedArray(), - PERMISSIONS_REQUEST_LOCATION - ) + requestPermissions(requiredPermissions.toTypedArray(), PERMISSIONS_REQUEST_LOCATION) } return } @@ -239,7 +257,16 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene AlarmManager.ELAPSED_REALTIME_WAKEUP, ALARM_MANAGER_INTERVAL.toLong(), ALARM_MANAGER_INTERVAL.toLong(), alarmIntent ) - BatteryOptimizationHelper().requestException(requireContext()) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q + && ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) { + requestingPermissions = true + showBackgroundLocationDialog(requireContext()) { + requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), PERMISSIONS_REQUEST_BACKGROUND_LOCATION) + } + } else { + requestingPermissions = BatteryOptimizationHelper().requestException(requireContext()) + } } else { sharedPreferences.edit().putBoolean(KEY_STATUS, false).apply() val preference = findPreference(KEY_STATUS) @@ -292,6 +319,7 @@ class MainFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListene const val KEY_BUFFER = "buffer" const val KEY_WAKELOCK = "wakelock" private const val PERMISSIONS_REQUEST_LOCATION = 2 + private const val PERMISSIONS_REQUEST_BACKGROUND_LOCATION = 3 } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ab94c14..567041c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -48,4 +48,6 @@ The app has been hidden. To open it again please dial 8722227 (TRACCAR). Please enter a valid http:// or https:// URL To continuously collect location data please turn off battery optimization for the app. + To continuously collect location data please enable \"%s\" permission. + Allow all the time