【问题标题】:How to request permission to make GPS ON in android如何在android中请求打开GPS的权限
【发布时间】:2018-08-14 21:20:21
【问题描述】:

我通过 FusedLocationProviderClient.getLastLocation() 获取用户的位置,但仅当用户已经打开位置时。 喜欢: https://i.stack.imgur.com/paQKO.png

如果位置关闭,我会得到空值。

在应用设置中显示已授予位置权限!!

帮助获取not null当前位置。


public class SelectGroup extends AppCompatActivity
        implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener{

    private static final String FINE_LOCATION = android.Manifest.permission.ACCESS_FINE_LOCATION;
    private static final String COARSE_LOCATION = android.Manifest.permission.ACCESS_COARSE_LOCATION;
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
    protected static final int REQUEST_CHECK_SETTINGS = 0x1;
    private GoogleApiClient mGoogleApiClient;

    private Boolean mLocationPermissionGranted = false;
    private FusedLocationProviderClient mFusedLocationProviderClient;

    private static final String TAG = "SelectGroup";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: starts");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_group);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        getLocationPermission();
    }

    //calling getDeviceLocation()
    private void init(){
        Log.d(TAG, "init: starts");
        if (mLocationPermissionGranted) {
            Log.d(TAG, "init: calling getDeviceLocation");

            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
                    (this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                Log.d(TAG, "init: returning");
                return;
            }
            getDeviceLocation();
        }
    }

    private void getDeviceLocation() {
        Log.d(TAG, "getDeviceLocation: getting devices current location");

        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        try {
            if (mLocationPermissionGranted) {

                Task location = mFusedLocationProviderClient.getLastLocation();
                location.addOnCompleteListener(new OnCompleteListener() {
                    @Override
                    public void onComplete(@NonNull Task task) {
                        if (task.isSuccessful()) {
                            Log.d(TAG, "onComplete: found location");
                            Location currentLocation = (Location) task.getResult();
                            //LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
                            Log.d(TAG, "onComplete: currentlocation is " + currentLocation);

                            if(currentLocation !=null) {
                                double lat = currentLocation.getLatitude();
                                double lon = currentLocation.getLongitude();

                                SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
                                SharedPreferences.Editor editor = pref.edit();
                                editor.putString("lat", lat + "");
                                editor.putString("lon", lon + "");
                                editor.apply();
                                Log.d(TAG, "onComplete: lat,lon : " + lat + "," + lon);
                            }
                            else {
                                Log.d(TAG, "onComplete: inside else where currentlocation is null");
                                settingsrequest();
                                Log.d(TAG, "onComplete: after settingsrequest");
                                double lat = currentLocation.getLatitude();
                                double lon = currentLocation.getLongitude();

                                SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
                                SharedPreferences.Editor editor = pref.edit();
                                editor.putString("lat", lat + "");
                                editor.putString("lon", lon + "");
                                editor.apply();
                            }
                        }
                    }
                });
            }

        } catch (SecurityException e) {
            Log.e(TAG, "getDeviceLocation: SecurityException " + e.getMessage());
        }
    }

    //calling init() after complete
    private void getLocationPermission(){
        String permissions[] = {android.Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};

        Log.d(TAG, "getLocationPermission: before if condition");
        if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
                FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
            if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
                    COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
                mLocationPermissionGranted = true;
                Log.d(TAG, "getLocationPermission: calling init");
                init();
            }else {
                ActivityCompat.requestPermissions(this,
                        permissions,
                        LOCATION_PERMISSION_REQUEST_CODE);
            }
        }else {
            ActivityCompat.requestPermissions(this,
                    permissions,
                    LOCATION_PERMISSION_REQUEST_CODE);
        }
    }

    //calling init() after complete
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        mLocationPermissionGranted = false;

        switch (requestCode){
            case LOCATION_PERMISSION_REQUEST_CODE:{
                if(grantResults.length > 0){
                    for(int i=0; i<grantResults.length;i++){
                        if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
                            mLocationPermissionGranted = false;
                            return;
                        }
                    }
                    mLocationPermissionGranted = true;
                    Toast.makeText(this, "Permission Granted : OnRequest", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "onRequestPermissionsResult: calling init");
                    init();
                }
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        //startLocationUpdates();
                        Log.d(TAG, "onActivityResult: Result Ok");
                        Toast.makeText(this, "Request : Result Ok", Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        //settingsrequest();//keep asking if imp or do whatever
                        Log.d(TAG, "onActivityResult: Result cancelled");
                        Toast.makeText(this, "Request : Result cancelled", Toast.LENGTH_SHORT).show();
                        break;
                }
                break;
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        settingsrequest();
    }

    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();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        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(SelectGroup.this, REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            // Ignore the error.
                            Toast.makeText(SelectGroup.this, "Error Occured", Toast.LENGTH_SHORT).show();
                        }
                        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;
                }
            }
        });
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.d(TAG, "onConnected: called");
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.d(TAG, "onConnectionSuspended: called");
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.d(TAG, "onConnectionFailed: called");
    }
}

我尝试了https://stackoverflow.com/a/38264716/8018480,但不明白如何使它成为可能!

【问题讨论】:

    标签: android google-maps android-studio


    【解决方案1】:

    您应该首先检查位置设置,如果有错误,请在请求最后一个位置之前解决

    LocationRequest request = LocationRequest.create();
    LocationSettingsRequest settingsRequest = new LocationSettingsRequest.Builder()
        .addLocationRequest(request)
        .build()
    LocationServices.getSettingsClient(this/*activity*/)
        .checkLocationSettings(settingsRequest)
        .addOnCompleteListener(new OnCompleteListener() {
            public void onComplete(Task task) {
                if(task.isSuccessful()) {
                    // ***REQUEST LAST LOCATION HERE***
                } else {
                    Exception e = task.getException()
                    if (e instanceOf ResolvableApiException) {
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult()
                        ((ResolvableApiException)e).startResolutionForResult(Activity.this, REQUEST_CHECK_SETTINGS);
                    } else {
                        //Location can not be resolved, inform the user
                    }
                }
            }
        });
    

    并在onActivityResult上检查startResolutionForResult的结果

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(intent);
        switch (requestCode) {
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        // All required changes were successfully made ...
                        // ***REQUEST LAST LOCATION HERE***
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to ...
                        break;
                default:
                    break;
            }
            break;
        }
    }
    

    参考:https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient

    【讨论】:

    • LocationRequest 对象无法放入 checkLocationSettings,它需要 LocationSettingsRequest。
    • 现在可以正常工作了,谢谢。我的代码中存在逻辑问题,所以我先调用你的函数来打开 GPS,然后再调用其他函数,这样现在 Location 永远不会为空。
    【解决方案2】:

    获得许可后,您可以检查 OnResume() 方法是 位置是打开还是关闭,同样检查权限。如果用户之后手动撤销了权限。

    参考https://stackoverflow.com/a/10311891/6816893

    【讨论】:

      猜你喜欢
      • 2022-12-13
      • 1970-01-01
      • 1970-01-01
      • 2017-02-28
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多