Ask user to turn on Location

后端 未结 5 1908
情深已故
情深已故 2020-12-16 21:44

How can I prompt the user to turn on Location?


The app is supposed to filter a list of locations with the current location of the user. If the

相关标签:
5条回答
  • 2020-12-16 22:02

    Use the below code snippet to open Device settings screen.

    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    startActivity(intent);
    

    else use settings API for permission dialog

    GoogleApiClient googleApiClient = new GoogleApiClient.Builder(mContext).addApi(LocationServices.API).build();
        googleApiClient.connect();
    
    LocationRequest lReq = LocationRequest.create();
    lReq.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    lReq.setInterval(10000);
    lReq.setFastestInterval(10000 / 2);
    
    LocationSettingsRequest.Builder lBuilder = new LocationSettingsRequest.Builder().addLocationRequest(lReq);
    lBuilder.setAlwaysShow(true);
    
    PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, lBuilder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    break;
            }
        }
    });
    
    0 讨论(0)
  • 2020-12-16 22:03

    You can use the following class for moving user to settings. First check for the location if it is not available call showSettingAlert

    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
    
    // Setting Dialog Title
    alertDialog.setTitle("GPS is settings");
    // Setting Dialog Message
    alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
    // On pressing Settings button
    alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
        }
    });
    
    // on pressing cancel button
    alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
        }
    });
    // Showing Alert Message
    alertDialog.show();
    
    0 讨论(0)
  • 2020-12-16 22:18

    Suppose your are doing all this stuff in an Activity name LocationActivity. You need to implement some callbacks for this purpose. Below is the code with comments so you can easily understand which method do what and when is called.

    Keep in mind to add permissions in app manifest file:

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

    Code for Ativity:

    import android.app.Activity;
    import android.app.Dialog;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.IntentSender;
    import android.content.pm.PackageManager;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v13.app.ActivityCompat;
    import android.support.v4.app.DialogFragment;
    import android.support.v4.app.FragmentActivity;
    
    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GoogleApiAvailability;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.common.api.PendingResult;
    import com.google.android.gms.common.api.ResultCallback;
    import com.google.android.gms.common.api.Status;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationServices;
    import com.google.android.gms.location.LocationSettingsRequest;
    import com.google.android.gms.location.LocationSettingsResult;
    import com.google.android.gms.location.LocationSettingsStatusCodes;
    
    public class LocationActivity extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener {
    
        // Unique tag for the error dialog fragment
        private static final String DIALOG_ERROR = "dialog_error";
        // Bool to track whether the app is already resolving an error
        private boolean mResolvingError = false;
        // Request code to use when launching the resolution activity
        private static final int REQUEST_RESOLVE_ERROR = 555;
    
        int ACCESS_FINE_LOCATION_CODE = 3310;
        int ACCESS_COARSE_LOCATION_CODE = 3410;
        private GoogleApiClient mGoogleApiClient;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // Build Google API Client for Location related work
            buildGoogleApiClient();
        }
    
    
        // When user first come to this activity we try to connect Google services for location and map related work
        protected synchronized void buildGoogleApiClient() {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
    
    
        // Google Api Client is connected
        @Override
        public void onConnected(Bundle bundle) {
            if (mGoogleApiClient.isConnected()) {
                //if connected successfully show user the settings dialog to enable location from settings services
                // If location services are enabled then get Location directly
                // Else show options for enable or disable location services
                settingsrequest();
            }
        }
    
    
        // This is the method that will be called if user has disabled the location services in the device settings
        // This will show a dialog asking user to enable location services or not
        // If user tap on "Yes" it will directly enable the services without taking user to the device settings
        // If user tap "No" it will just Finish the current Activity
        public void settingsrequest() {
            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(30 * 1000);
            locationRequest.setFastestInterval(5 * 1000);
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
            builder.setAlwaysShow(true); //this is the key ingredient
    
            PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
                @Override
                public void onResult(LocationSettingsResult result) {
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.SUCCESS:
                            if (mGoogleApiClient.isConnected()) {
    
                                // check if the device has OS Marshmellow or greater than
                                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
                                    if (ActivityCompat.checkSelfPermission(LocationActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(LocationActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                                        ActivityCompat.requestPermissions(LocationActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_FINE_LOCATION_CODE);
                                    } else {
                                        // get Location
                                    }
                                } else {
                                    // get Location
                                }
    
                            }
                            break;
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be fixed by showing the user
                            // a dialog.
                            try {
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult(LocationActivity.this, REQUEST_RESOLVE_ERROR);
                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the 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;
                    }
                }
            });
        }
    
    
        // This method is called only on devices having installed Android version >= M (Marshmellow)
        // This method is just to show the user options for allow or deny location services at runtime
        @Override
        public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
            switch (requestCode) {
                case 3310: {
    
                    if (grantResults.length > 0) {
    
                        for (int i = 0, len = permissions.length; i < len; i++) {
    
                            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                                // Show the user a dialog why you need location
                            } else if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                                // get Location
                            } else {
                                this.finish();
                            }
                        }
                    }
                    return;
                }
            }
        }
    
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == REQUEST_RESOLVE_ERROR) {
                mResolvingError = false;
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // get location method
                        break;
                    case Activity.RESULT_CANCELED:
                        this.finish();
                        break;
                }
            }
        }
    
    
        @Override
        public void onConnectionSuspended(int i) {
        }
    
    
        // When there is an error connecting Google Services
        @Override
        public void onConnectionFailed(ConnectionResult result) {
            if (mResolvingError) {
                // Already attempting to resolve an error.
                return;
            } else if (result.hasResolution()) {
                try {
                    mResolvingError = true;
                    result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
                } catch (IntentSender.SendIntentException e) {
                    // There was an error with the resolution intent. Try again.
                    mGoogleApiClient.connect();
                }
            } else {
                // Show dialog using GoogleApiAvailability.getErrorDialog()
                showErrorDialog(result.getErrorCode());
                mResolvingError = true;
            }
        }
    
    
        /* Creates a dialog for an error message */
        private void showErrorDialog(int errorCode) {
            // Create a fragment for the error dialog
            ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
            // Pass the error that should be displayed
            Bundle args = new Bundle();
            args.putInt(DIALOG_ERROR, errorCode);
            dialogFragment.setArguments(args);
            dialogFragment.show(getSupportFragmentManager(), "errordialog");
        }
    
        /* Called from ErrorDialogFragment when the dialog is dismissed. */
        public void onDialogDismissed() {
            mResolvingError = false;
        }
    
        /* A fragment to display an error dialog */
        public static class ErrorDialogFragment extends DialogFragment {
            public ErrorDialogFragment() {
            }
    
            @Override
            public Dialog onCreateDialog(Bundle savedInstanceState) {
                // Get the error code and retrieve the appropriate dialog
                int errorCode = this.getArguments().getInt(DIALOG_ERROR);
                return GoogleApiAvailability.getInstance().getErrorDialog(
                        this.getActivity(), errorCode, REQUEST_RESOLVE_ERROR);
            }
    
            @Override
            public void onDismiss(DialogInterface dialog) {
                ((LocationActivity) getActivity()).onDialogDismissed();
            }
        }
    
    
        // Connect Google Api Client if it is not connected already
        @Override
        protected void onStart() {
            super.onStart();
            if (mGoogleApiClient != null) {
                mGoogleApiClient.connect();
            }
        }
    
        // Stop the service when we are leaving this activity
        @Override
        protected void onStop() {
            super.onStop();
            if (mGoogleApiClient != null) {
                mGoogleApiClient.disconnect();
            }
        }
    
    }
    

    You can read the official docs here

    0 讨论(0)
  • 2020-12-16 22:23

    Try

    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);
     }
    }
    
    private void turnGPSOff(){
       String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
    
       if(provider.contains("gps")){ //if gps is enabled
        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);
    }
    }
    
    private boolean canToggleGPS() {
       PackageManager pacman = getPackageManager();
    PackageInfo pacInfo = null;
    
       try {
        pacInfo = pacman.getPackageInfo("com.android.settings", PackageManager.GET_RECEIVERS);
       } catch (NameNotFoundException e) {
        return false; //package not found
       }
    
       if(pacInfo != null){
        for(ActivityInfo actInfo : pacInfo.receivers){
            //test if recevier is exported. if so, we can toggle GPS.
            if(actInfo.name.equals("com.android.settings.widget.SettingsAppWidgetProvider") && actInfo.exported){
                return true;
            }
        }
     }
    
     return false; //default
    }
    
    0 讨论(0)
  • 2020-12-16 22:26

    Found the solution I was asking for.


    Requirements

    Nuget Xamarin.GooglePlayServices.Location


    Code

    Int64
        interval = 1000 * 60 * 1,
        fastestInterval = 1000 * 50;
    
    try {
        GoogleApiClient
            googleApiClient = new GoogleApiClient.Builder( this )
                .AddApi( LocationServices.API )
                .Build();
    
        googleApiClient.Connect();
    
        LocationRequest
            locationRequest = LocationRequest.Create()
                .SetPriority( LocationRequest.PriorityBalancedPowerAccuracy )
                .SetInterval( interval )
                .SetFastestInterval( fastestInterval );
    
        LocationSettingsRequest.Builder
            locationSettingsRequestBuilder = new LocationSettingsRequest.Builder()
                .AddLocationRequest( locationRequest );
    
        locationSettingsRequestBuilder.SetAlwaysShow( false );
    
        LocationSettingsResult
            locationSettingsResult = await LocationServices.SettingsApi.CheckLocationSettingsAsync(
                googleApiClient, locationSettingsRequestBuilder.Build() );
    
        if( locationSettingsResult.Status.StatusCode == LocationSettingsStatusCodes.ResolutionRequired ) {
            locationSettingsResult.Status.StartResolutionForResult( this, 0 );
        }
    } catch( Exception exception ) {
        // Log exception
    }
    

    With this code, if the locationSettingsResult.Status.StatusCode is LocationSettingsStatusCodes.ResolutionRequired ( 6 ) it means -- probably -- that the Location is turned off, although I've found one situation that it didn't return the value when the device had the option turned off. After turning on and off, it worked, might be a bug on the device, or not.

    0 讨论(0)
提交回复
热议问题