Search code examples
androidkotlinandroid-permissionsandroid-locationandroid-gps

How to solve problem with gps permissions on Android versions 12?


GPS service is not enabled on Android versions 12 and above. Everything worked correctly on earlier versions

I have read this documentation, but I'm not sure if I have a problem with android:foregroundServiceType since I basically don't use it in the application.

So here is some of my code AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

And code of my vm:

private fun enableGps(activity: FragmentActivity) {
    val manager = activity.getSystemService(Context.LOCATION_SERVICE) as LocationManager
    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(manager)) {
        locationManager.enableGps(activity)
    }
}

And here is the implementation of the method itself:

override fun enableGps(activity: FragmentActivity) {
    if (googleApiClient == null) {
        googleApiClient = GoogleApiClient.Builder(context)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks {
                override fun onConnected(bundle: Bundle?) {}
                override fun onConnectionSuspended(i: Int) {
                    googleApiClient?.connect()
                }
            })
            .addOnConnectionFailedListener { connectionResult ->
                Timber.e("${connectionResult.errorCode}")
            }.build()
        googleApiClient?.connect()
    }
    val locationRequest = LocationRequest.create()
    locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    locationRequest.interval = 10000
    locationRequest.fastestInterval = 5000
    val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
    builder.setAlwaysShow(true)
    googleApiClient?.let {
        val result: PendingResult<LocationSettingsResult> =
            LocationServices.SettingsApi.checkLocationSettings(it, builder.build())
        result.setResultCallback { result ->
            val status: Status = result.status
            when (status.statusCode) {
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
                    // Show the dialog by calling startResolutionForResult(),
                    status.startResolutionForResult(
                        activity,
                        REQUEST_LOCATION
                    )
                } catch (e: IntentSender.SendIntentException) {
                    Timber.e(e)
                }
                LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                    activity.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
                }
            }
        }
    }
}

UPD Here is full code of my DeviceLocationManager, maybe I 'm requesting my permissions somehow wrong here: https://gist.github.com/mnewlive/0c0a0c1f7ccb26fe58fd6b0fa5dd1dda


Solution

  • I rewrote the following method because it was deprecated:

    override fun isLocationProviderActive(): Boolean {
        val providerInfo = Settings.Secure.getString(
            context.contentResolver,
            Settings.Secure.LOCATION_PROVIDERS_ALLOWED
        )
        return providerInfo?.isNotEmpty() == true
    }
    

    to

    override fun isLocationStateEnabled(): Boolean {
        val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        return LocationManagerCompat.isLocationEnabled(locationManager)
    }