打开位置服务,而不导航到设置页面

与传统的提示用户转到设置页面并启用定位服务并再次返回的方法相反,我注意到在一些最新的应用程序中执行相同的更简单的方法。

参考下面的截图,它会提示一个对话框,用户只需点击一下就可以启用定位服务,并且可以在这些应用程序中运行。

我怎样才能达到相同的?

在这里输入图像说明

该对话框由Google Play服务中的LocationSettingsRequest.Builder创build。

你需要添加一个依赖到你的应用程序build.gradle

 compile 'com.google.android.gms:play-services-location:10.0.1' 

那么你可以使用这个最小的例子:

 private void displayLocationSettingsRequest(Context context) { GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context) .addApi(LocationServices.API).build(); googleApiClient.connect(); LocationRequest locationRequest = LocationRequest.create(); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); locationRequest.setInterval(10000); locationRequest.setFastestInterval(10000 / 2); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest); builder.setAlwaysShow(true); PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build()); result.setResultCallback(new ResultCallback<LocationSettingsResult>() { @Override public void onResult(LocationSettingsResult result) { final Status status = result.getStatus(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.SUCCESS: Log.i(TAG, "All location settings are satisfied."); break; case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings "); try { // Show the dialog by calling startResolutionForResult(), and check the result // in onActivityResult(). status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS); } catch (IntentSender.SendIntentException e) { Log.i(TAG, "PendingIntent unable to execute request."); } break; case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE: Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created."); break; } } }); } 

你可以在这里find完整的例子。

Android Marshmallow 6支持运行时权限。 运行时权限只能在棉花糖上工作,在棉花糖之前,它仍然是旧的方式。

您可以在此Android Developer官方video中了解更多信息:

https://www.youtube.com/watch?v=C8lUdPVSzDk

并请求权限: http : //developer.android.com/training/permissions/requesting.html

谢谢Mattia Maestrini的答复,我想补充一点,使用

compile 'com.google.android.gms:play-services-location:8.1.0'

就足够了。 这可以防止您的应用程序包括不必要的库,并有助于保持您的方法计数低

其工作类似于谷歌地图

在build.gradle文件中添加依赖项

编译“com.google.android.gms:play-services:8.3.0”

 this or that 

编译“com.google.android.gms:play-services-location:10.0.1”

在这里输入图像说明 包com.keshav.volleypostexample;

 import android.content.Context; import android.content.IntentSender; import android.location.LocationManager; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; 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; import java.util.List; public class LocationOnOff_Similar_To_Google_Maps extends AppCompatActivity { protected static final String TAG = "LocationOnOff"; private GoogleApiClient googleApiClient; final static int REQUEST_LOCATION = 199; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setFinishOnTouchOutside(true); // Todo Location Already on ... start final LocationManager manager = (LocationManager) LocationOnOff_Similar_To_Google_Maps.this.getSystemService(Context.LOCATION_SERVICE); if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) { Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show(); finish(); } // Todo Location Already on ... end if(!hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)){ Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not Supported",Toast.LENGTH_SHORT).show(); } if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) { Log.e("keshav","Gps already enabled"); Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not enabled",Toast.LENGTH_SHORT).show(); enableLoc(); }else{ Log.e("keshav","Gps already enabled"); Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show(); } } private boolean hasGPSDevice(Context context) { final LocationManager mgr = (LocationManager) context .getSystemService(Context.LOCATION_SERVICE); if (mgr == null) return false; final List<String> providers = mgr.getAllProviders(); if (providers == null) return false; return providers.contains(LocationManager.GPS_PROVIDER); } private void enableLoc() { if (googleApiClient == null) { googleApiClient = new GoogleApiClient.Builder(LocationOnOff_Similar_To_Google_Maps.this) .addApi(LocationServices.API) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { googleApiClient.connect(); } }) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d("Location error","Location error " + connectionResult.getErrorCode()); } }).build(); googleApiClient.connect(); 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); PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build()); result.setResultCallback(new ResultCallback<LocationSettingsResult>() { @Override public void onResult(LocationSettingsResult result) { final Status status = result.getStatus(); switch (status.getStatusCode()) { case LocationSettingsStatusCodes.RESOLUTION_REQUIRED: try { // Show the dialog by calling startResolutionForResult(), // and check the result in onActivityResult(). status.startResolutionForResult(LocationOnOff_Similar_To_Google_Maps.this, REQUEST_LOCATION); finish(); } catch (IntentSender.SendIntentException e) { // Ignore the error. } break; } } }); } } } 

随着最近棉花糖的更新,即使打开位置设置,你的应用程序将需要明确要求许可。 推荐的方法是显示你的应用的权限部分,其中用户可以根据需要切换权限。 这样做的代码片段如下所示:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Location Permission"); builder.setMessage("The app needs location permissions. Please grant this permission to continue using the features of the app."); builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION); } }); builder.setNegativeButton(android.R.string.no, null); builder.show(); } } else { // do programatically as show in the other answer } 

并重写onRequestPermissionsResult方法如下:

 @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_COARSE_LOCATION: { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.d(TAG, "coarse location permission granted"); } else { Intent intent = new Intent(); intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); } } } } 

另一种方法是您也可以使用SettingsApi查询启用了哪个位置提供程序。 如果没有启用,您可以提示一个对话框来更改应用程序中的设置。

感谢Mattia Maestrini +1

Xamarin解决scheme:

 using Android.Gms.Common.Apis; using Android.Gms.Location; public const int REQUEST_CHECK_SETTINGS = 0x1; private void DisplayLocationSettingsRequest() { var googleApiClient = new GoogleApiClient.Builder(this).AddApi(LocationServices.API).Build(); googleApiClient.Connect(); var locationRequest = LocationRequest.Create(); locationRequest.SetPriority(LocationRequest.PriorityHighAccuracy); locationRequest.SetInterval(10000); locationRequest.SetFastestInterval(10000 / 2); var builder = new LocationSettingsRequest.Builder().AddLocationRequest(locationRequest); builder.SetAlwaysShow(true); var result = LocationServices.SettingsApi.CheckLocationSettings(googleApiClient, builder.Build()); result.SetResultCallback((LocationSettingsResult callback) => { switch (callback.Status.StatusCode) { case LocationSettingsStatusCodes.Success: { DoStuffWithLocation(); break; } case LocationSettingsStatusCodes.ResolutionRequired: { try { // Show the dialog by calling startResolutionForResult(), and check the result // in onActivityResult(). callback.Status.StartResolutionForResult(this, REQUEST_CHECK_SETTINGS); } catch (IntentSender.SendIntentException e) { } break; } default: { // If all else fails, take the user to the android location settings StartActivity(new Intent(Android.Provider.Settings.ActionLocationSourceSettings)); break; } } }); } protected override void OnActivityResult(int requestCode, Android.App.Result resultCode, Intent data) { switch (requestCode) { case REQUEST_CHECK_SETTINGS: { switch (resultCode) { case Android.App.Result.Ok: { DoStuffWithLocation(); break; } case Android.App.Result.Canceled: { //No location break; } } break; } } }