0

When I try to turn on gps without going to the phone settings, I get this dialog:

enter image description here

How could I display a dialog with such a description? enter image description here

Here is example of my code:

viewModel.onEnableGpsEvent.observe(this, Observer { event ->
    event.getContentIfNotHandled()?.let {
        activity?.let {
            val locationRequest = LocationRequest.create()
            locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
            val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
            val task = LocationServices.getSettingsClient(it).checkLocationSettings(builder.build())

            task.addOnSuccessListener { response ->
                val states = response.locationSettingsStates
                if (states.isLocationPresent) {
                    //TODO: Do something if need it
                }
            }
            task.addOnFailureListener { e ->
                if (e is ResolvableApiException) {
                    try {
                        // Handle result in onActivityResult()
                        e.startResolutionForResult(
                            it,
                            LOCATION_SETTING_REQUEST
                        )
                    } catch (sendEx: IntentSender.SendIntentException) {
                    }
                }
            }
        }

Also i have next depedencies:

implementation 'com.google.android.gms:play-services-location:18.0.0'
Morozov
  • 4,968
  • 6
  • 39
  • 70

2 Answers2

1

This is my approach used in Fragment:

  1. Create Extension Function for Requesting GPS Function:

     fun Fragment.requestGPSOn(request: ActivityResultLauncher<IntentSenderRequest>) {   //new api
         val locationRequest = LocationRequest.create().apply {
             priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY     //GPS accuracy
         }
    
         val settingRequest = LocationSettingsRequest.Builder().run {
             addLocationRequest(locationRequest)
             build()
         }
    
         val settingsClient = LocationServices.getSettingsClient(requireContext())
         val task = settingsClient.checkLocationSettings(settingRequest)         //【fire and receive result】
    
         task.addOnFailureListener {                             //if GPS is not on currently
             val intentSender = (it as ResolvableApiException).resolution.intentSender
             val intentSenderRequest = IntentSenderRequest.Builder(intentSender).build()
    
             request.launch(intentSenderRequest)
         }
     }
    
  2. Setup in Fragment:

     class FirstFragment : Fragment() {
         private lateinit var binding: FragmentFirstBinding
         private lateinit var gpsOnRequest: ActivityResultLauncher<IntentSenderRequest>
    
         override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
             binding = DataBindingUtil.inflate(inflater, R.layout.fragment_first, container, false)
             gpsOnRequest = getGPSOnRequest()
    
             binding.gpsOnButton.setOnClickListener {
                 requestGPSOn(gpsOnRequest)      //extension function, 【will apply specified accuracy even already on!!】
             }
    
             return binding.root
         }
    
         private fun getGPSOnRequest() = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
             if (result.resultCode != RESULT_OK) {
                 //do your stuff
             }
         }
     }
    

Demo: https://youtu.be/nWsSADUmGzM


For checking GPS status:

fun Fragment.isGPSOn(): Boolean {
    val locationManager = requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager

    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
}

Be in mind, startActivityForResult() and startIntentSenderForResult() are already deprecated, new Result api check out this official video: https://youtu.be/oP-zXjkT0C0.

Sam Chen
  • 7,597
  • 2
  • 40
  • 73
0

Solved this problem with next solution:

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)
    val result: PendingResult<LocationSettingsResult> = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, 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))
            }
        }
    }
}
Morozov
  • 4,968
  • 6
  • 39
  • 70