How to ask user to enable GPS at the launch of application?

21,710

Solution 1

If you want something as shown in below image, follow along.

Permission for GPS

  1. Add the following dependencies in your app build.gradle

      implementation 'com.google.android.gms:play-services-location:16.0.0'
    
  2. Create the type of location request you want, we want high accuracy for GPS

      LocationRequest locationRequest = LocationRequest.create();
      locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
      LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);
    
  3. Now we need to check current state of GPS. For this, we have to use LocationServices.getSettingsClient(getActivity()).checkLocationSettings(builder.build()) This will return a Task which needs to handled asynchronously. In RESOLUTION_REQUIRED case, we ask user to give permissions, this is where we show the user prompt to enable GPS.

    Task<LocationSettingsResponse> result =
                    LocationServices.getSettingsClient(getActivity()).checkLocationSettings(builder.build());
    
    
    
    result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
                @Override
                public void onComplete(@NonNull Task<LocationSettingsResponse> task) {
                    try {
                        LocationSettingsResponse response = task.getResult(ApiException.class);
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                    } catch (ApiException exception) {
                        switch (exception.getStatusCode()) {
                            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                // Location settings are not satisfied. But could be fixed by showing the
                                // user a dialog.
                                try {
                                    // Cast to a resolvable exception.
                                    ResolvableApiException resolvable = (ResolvableApiException) exception;
                                    // Show the dialog by calling startResolutionForResult(),
                                    // and check the result in onActivityResult().
                                    resolvable.startResolutionForResult(
                                            getActivity(),
                                            LocationRequest.PRIORITY_HIGH_ACCURACY);
                                } catch (IntentSender.SendIntentException e) {
                                    // Ignore the error.
                                } catch (ClassCastException e) {
                                    // Ignore, should be an impossible error.
                                }
                                break;
                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                // Location settings are not satisfied. However, we have no way to fix the
                                // settings so we won't show the dialog.
                                break;
                        }
                    }
                }
            });
    
  4. Now that we have asked user to turn on GPS, we need to check whether user allowed it or ignored it. For this, override onActivityResult. Please note that, if you're implementing above code in a fragment, result will be received in the enclosing Activity. So override onActivityResult in the Activity class.

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case LocationRequest.PRIORITY_HIGH_ACCURACY:
            switch (resultCode) {
                case Activity.RESULT_OK:
                    // All required changes were successfully made
                    Log.i(TAG, "onActivityResult: GPS Enabled by user");
                    break;
                case Activity.RESULT_CANCELED:
                    // The user was asked to change settings, but chose not to
                    Log.i(TAG, "onActivityResult: User rejected GPS request");
                    break;
                default:
                    break;
            }
            break;
        } 
    }
    

From Android Documentation

Solution 2

This is the kotlin implementation of @Ananth answer

private fun showLocationPrompt() {
        val locationRequest = LocationRequest.create()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)

        val result: Task<LocationSettingsResponse> = LocationServices.getSettingsClient(activity).checkLocationSettings(builder.build())

        result.addOnCompleteListener { task ->
            try {
                val response = task.getResult(ApiException::class.java)
                // All location settings are satisfied. The client can initialize location
                // requests here.
            } catch (exception: ApiException) {
                when (exception.statusCode) {
                    LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
                        try {
                            // Cast to a resolvable exception.
                            val resolvable: ResolvableApiException = exception as ResolvableApiException
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            resolvable.startResolutionForResult(
                                activity, LocationRequest.PRIORITY_HIGH_ACCURACY
                            )
                        } catch (e: IntentSender.SendIntentException) {
                            // Ignore the error.
                        } catch (e: ClassCastException) {
                            // Ignore, should be an impossible error.
                        }
                    }
                    LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                        // Location settings are not satisfied. But could be fixed by showing the
                        // user a dialog.

                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                    }
                }
            }
        }
    }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            LocationRequest.PRIORITY_HIGH_ACCURACY -> {
                if (resultCode == Activity.RESULT_OK) {
                    Log.e("Status: ","On")
                } else {
                    Log.e("Status: ","Off")
                }
            }
        }
    }

Solution 3

use SettingsApi if you not want to force user to go settings page to enable gps. here the link of how to use SettingsApi SettingsApi

Share:
21,710
Mishu
Author by

Mishu

Updated on November 12, 2020

Comments

  • Mishu
    Mishu over 3 years
    private void turnGPSOn(){
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
    
    if(!provider.contains("gps")){ //if gps is disabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); 
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
    }
    }
    

    see the Logcat

    04/20 17:35:26: Launching app
    $ adb push F:\AndroidProject\Picker\app\build\outputs\apk\app-debug.apk /data/local/tmp/picker.novasyslabs.com.picker
    $ adb shell pm install -r "/data/local/tmp/picker.novasyslabs.com.picker"
        pkg: /data/local/tmp/picker.novasyslabs.com.picker
    Success
    
    
    $ adb shell am start -n "picker.novasyslabs.com.picker/picker.novasyslabs.com.picker.SlashScreen" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
    Connected to process 22502 on device sony-d2302-ZH80065A89
    W/ResourceType: Found multiple library tables, ignoring...
    W/ResourceType: Found multiple library tables, ignoring...
    W/ResourceType: Found multiple library tables, ignoring...
    W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
    I/art: Background partial concurrent mark sweep GC freed 151(19KB) AllocSpace objects, 0(0B) LOS objects, 39% free, 13MB/22MB, paused 5.156ms total 20.919ms
    D/AndroidRuntime: Shutting down VM
    E/AndroidRuntime: FATAL EXCEPTION: main
                      Process: picker.novasyslabs.com.picker, PID: 22502
                      java.lang.RuntimeException: Unable to start activity ComponentInfo{picker.novasyslabs.com.picker/picker.novasyslabs.com.picker.SlashScreen}: java.lang.ClassCastException: picker.novasyslabs.com.picker.SlashScreen cannot be cast to com.google.android.gms.common.api.GoogleApiClient$ConnectionCallbacks
                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
                          at android.app.ActivityThread.access$800(ActivityThread.java:156)
                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
                          at android.os.Handler.dispatchMessage(Handler.java:102)
                          at android.os.Looper.loop(Looper.java:211)
                          at android.app.ActivityThread.main(ActivityThread.java:5371)
                          at java.lang.reflect.Method.invoke(Native Method)
                          at java.lang.reflect.Method.invoke(Method.java:372)
                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945)
                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740)
                       Caused by: java.lang.ClassCastException: picker.novasyslabs.com.picker.SlashScreen cannot be cast to com.google.android.gms.common.api.GoogleApiClient$ConnectionCallbacks
                          at picker.novasyslabs.com.picker.SlashScreen.onCreate(SlashScreen.java:65)
                          at android.app.Activity.performCreate(Activity.java:5990)
                          at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442) 
                          at android.app.ActivityThread.access$800(ActivityThread.java:156) 
                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351) 
                          at android.os.Handler.dispatchMessage(Handler.java:102) 
                          at android.os.Looper.loop(Looper.java:211) 
                          at android.app.ActivityThread.main(ActivityThread.java:5371) 
                          at java.lang.reflect.Method.invoke(Native Method) 
                          at java.lang.reflect.Method.invoke(Method.java:372) 
                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:945) 
                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:740) 
    Application terminated.
    

    I tried many other option like package manager, location manager, etc but not able to do what I want. I want that at the launch application user will be prompted to enable the GPS. I don't want user to go inside the settings.

    And that I wanted for the API level >=19.

    Please help me to solve my problem......... Thanks

  • CommonsWare
    CommonsWare about 7 years
    The question has 'I don't want user to go inside the settings."
  • Arsalan Khan
    Arsalan Khan about 7 years
    No, final decision rely on user either GPS on or off
  • Arsalan Khan
    Arsalan Khan about 7 years
    you prompt this dialog until GPS on
  • Ananth
    Ananth about 5 years
    This has been deprecated.