Location permission fixes (#135)

* Fixed bug where ACCESS_BACKGROUND_LOCATION was used below API level 29. Removed ACCESS_COARSE_LOCATION permission since it has no purpose when ACCESS_FINE_LOCATION is used.

* Added a more generic validatePermissions to PermissionManager and renamed haveLocationPermissions to hasLocationPermissions.
This commit is contained in:
jobhh 2019-12-12 17:34:58 +01:00 committed by Paulus Schoutsen
parent 149ec161f5
commit b8a9737d18
5 changed files with 40 additions and 34 deletions

View file

@ -6,7 +6,6 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
@ -47,4 +46,4 @@
android:parentActivityName=".webview.WebViewActivity"/>
</application>
</manifest>
</manifest>

View file

@ -1,17 +1,14 @@
package io.homeassistant.companion.android.background
import android.Manifest.permission.ACCESS_COARSE_LOCATION
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.location.Location
import android.os.BatteryManager
import android.os.Build
import android.util.Log
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.Geofence
import com.google.android.gms.location.GeofencingEvent
import com.google.android.gms.location.GeofencingRequest
@ -21,6 +18,7 @@ import com.google.android.gms.location.LocationServices
import io.homeassistant.companion.android.common.dagger.GraphComponentAccessor
import io.homeassistant.companion.android.domain.integration.IntegrationUseCase
import io.homeassistant.companion.android.domain.integration.UpdateLocation
import io.homeassistant.companion.android.util.PermissionManager
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -69,11 +67,7 @@ class LocationBroadcastReceiver : BroadcastReceiver() {
}
private fun setupLocationTracking(context: Context) {
if (ActivityCompat.checkSelfPermission(
context,
ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
if (!PermissionManager.hasLocationPermissions(context)) {
Log.w(TAG, "Not starting location reporting because of permissions.")
return
}

View file

@ -60,7 +60,7 @@ class MobileAppIntegrationFragment : Fragment(), MobileAppIntegrationView {
}
override fun deviceRegistered() {
if (!PermissionManager.haveLocationPermissions(context!!)) {
if (!PermissionManager.hasLocationPermissions(context!!)) {
PermissionManager.requestLocationPermissions(this)
} else {
// If we have permission already we can just continue with

View file

@ -35,7 +35,7 @@ class SettingsFragment : PreferenceFragmentCompat(), SettingsView {
}
override fun onLocationSettingChanged() {
if (!PermissionManager.haveLocationPermissions(context!!)) {
if (!PermissionManager.hasLocationPermissions(context!!)) {
PermissionManager.requestLocationPermissions(this)
}
PermissionManager.restartLocationTracking(context!!, activity!!)

View file

@ -1,7 +1,6 @@
package io.homeassistant.companion.android.util
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
@ -14,30 +13,44 @@ import io.homeassistant.companion.android.background.LocationBroadcastReceiver
class PermissionManager {
companion object {
private const val LOCATION_REQUEST_CODE = 1
const val LOCATION_REQUEST_CODE = 1
fun haveLocationPermissions(context: Context): Boolean {
return ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
/**
* Check if the a given permission is granted
*/
fun hasPermission(context: Context, permission: String): Boolean {
return ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
}
@SuppressLint("InlinedApi")
/**
* Returns TRUE if all permissions in the grantResults were granted
*/
fun arePermissionsGranted(grantResults: IntArray): Boolean {
return grantResults.all { it == PackageManager.PERMISSION_GRANTED }
}
/**
* Check if the required location permissions are granted
*/
fun hasLocationPermissions(context: Context): Boolean {
for (permission in getLocationPermissionArray()) {
if (!hasPermission(context, permission)) {
return false
}
}
return true
}
/**
* Returns an Array with required location permissions.
* ACCESS_FINE_LOCATION and, if API level >= 29, ACCESS_BACKGROUND_LOCATION.
*/
fun getLocationPermissionArray(): Array<String> {
var retVal = arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
)
if (Build.VERSION.SDK_INT >= 21)
retVal = retVal.plus(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
return retVal
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
} else {
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
}
}
fun validateLocationPermissions(
@ -45,7 +58,7 @@ class PermissionManager {
permissions: Array<out String>,
grantResults: IntArray
): Boolean {
return requestCode == LOCATION_REQUEST_CODE && grantResults.all { it == PackageManager.PERMISSION_GRANTED }
return requestCode == LOCATION_REQUEST_CODE && arePermissionsGranted(grantResults)
}
fun requestLocationPermissions(fragment: Fragment) {