如何显示 Google 地图之类的启用位置对话框?
How to show enable location dialog like Google maps?
我使用最新版本的 Google Play Services (7.0) 并按照他们的指南中给出的步骤进行操作,我启用了如下所示的位置对话框,其中有一个 "never" 按钮。我的应用程序强制需要位置,所以我不想向用户显示 "never",因为一旦用户点击 "never",我就根本无法获取位置或再次请求位置。
因为 Google 地图只有是和没有按钮而没有从不按钮,知道如何实现相同的吗?
我的应用程序图片
Google 地图的图像
LocationSettingsRequest.Builder 有一个方法 setAlwaysShow(boolean show)
。 虽然文档表明它当前什么都不做(更新于 2015-07-05:更新的 Google 文档已删除此措辞),设置 builder.setAlwaysShow(true);
将启用 Google 地图行为:
这是让它工作的代码:
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).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); //this is the key ingredient
//**************************
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();
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(
getActivity(), 1000);
} 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;
}
}
});
}
对于 Kotlin,请参阅此处:
我想为那些正在寻找处理 Yes/No 按钮的人添加对 kai 的回答的一些更改。
在您的 activity
中声明此常量
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
在您的 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(MainActivity.this, REQUEST_CHECK_SETTINGS);
} 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;
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
settingsrequest();//keep asking if imp or do whatever
break;
}
break;
}
}
Ola Cabs 正在使用新发布的设置 API 来实现此功能。根据新的 API,用户无需导航至设置页面即可启用位置服务,从而实现无缝集成。请阅读以下内容了解更多详情:
https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi
它的工作方式类似于 google 地图?
源代码:https://drive.google.com/open?id=0BzBKpZ4nzNzUOXM2eEhHM3hOZk0
在 build.gradle 文件中添加依赖项:
compile 'com.google.android.gms:play-services:8.3.0'
或
compile 'com.google.android.gms:play-services-location:10.0.1'
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;
}
}
});
}
}
}
依赖关系
compile 'com.google.android.gms:play-services-location:10.0.1'
代码
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
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.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final int REQUEST_LOCATION=001;
GoogleApiClient googleApiClient;
LocationManager locationManager;
LocationRequest locationRequest;
LocationSettingsRequest.Builder locationSettingsRequest;
Context context;
PendingResult<LocationSettingsResult> pendingResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Toast.makeText(this, "Gps is Enabled", Toast.LENGTH_SHORT).show();
} else {
mEnableGps();
}
}
public void mEnableGps() {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
mLocationSetting();
}
public void mLocationSetting() {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(1 * 1000);
locationRequest.setFastestInterval(1 * 1000);
locationSettingsRequest = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
mResult();
}
public void mResult() {
pendingResult = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, locationSettingsRequest.build());
pendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(MainActivity.this, REQUEST_LOCATION);
} catch (IntentSender.SendIntentException e) {
}
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;
}
}
});
}
//callback method
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case REQUEST_LOCATION:
switch (resultCode) {
case Activity.RESULT_OK:
// All required changes were successfully made
Toast.makeText(context, "Gps enabled", Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
Toast.makeText(context, "Gps Canceled", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
break;
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
您还可以为 Builder 添加多个 LocationRequests 以实现 "Use GPS, Wi-Fi and mobile networks for location" 对话框而不是 "Use GPS for location"
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY))
.addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_HIGH_ACCURACY))
.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
LocationServices.SettingsApi 现在已弃用,所以我们使用 SettingsClient
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10);
mLocationRequest.setSmallestDisplacement(10);
mLocationRequest.setFastestInterval(10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new
LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
然后检查是否满足当前位置设置。
创建 LocationSettingsResponse 任务:
Task<LocationSettingsResponse> task=LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
然后添加监听器
task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
@Override
public void onComplete(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(
HomeActivity.this,
101);
} 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;
}
}
}
});
已添加 onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case 101:
switch (resultCode) {
case Activity.RESULT_OK:
// All required changes were successfully made
Toast.makeText(HomeActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
Toast.makeText(HomeActivity.this,"Canceled",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
break;
}
}
在 Kotlin 中,使用此代码:
import android.app.Activity
import android.content.Intent
import android.content.IntentSender
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.PendingResult
import com.google.android.gms.common.api.Status
import com.google.android.gms.location.*
class MainActivity : AppCompatActivity() {
private var googleApiClient: GoogleApiClient? = null
private val REQUESTLOCATION = 199
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableLoc()
}
private fun enableLoc() {
googleApiClient = GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks {
override fun onConnected(bundle: Bundle?) {}
override fun onConnectionSuspended(i: Int) {
googleApiClient?.connect()
}
})
.addOnConnectionFailedListener {
}.build()
googleApiClient?.connect()
val locationRequest = LocationRequest.create()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest.interval = 30 * 1000.toLong()
locationRequest.fastestInterval = 5 * 1000.toLong()
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 {
status.startResolutionForResult(
this@MainActivity,
REQUESTLOCATION
)
} catch (e: IntentSender.SendIntentException) {
}
}
}
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUESTLOCATION -> when (resultCode) {
Activity.RESULT_OK -> Log.d("abc","OK")
Activity.RESULT_CANCELED -> Log.d("abc","CANCEL")
}
}
}
}
请查看我在前台获取用户位置的非常简单的解决方案。
- GPS 设置对话框
- 具有实时数据的用户位置。
- LocationUtility class activity 生命周期感知 pause/resume 位置更新。
- 位置最新 FusedLocationProviderClient
2020 年 8 月新的更新答案
enter link description here
如果你在 activity
中使用,我的片段就像这个更新
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
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.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
public class FragmentSearch extends Fragment
{
View SearchFragmentview;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
SearchFragmentview=inflater.inflate(R.layout.fragment_search,container,false);
getLocationDialog();
return SearchFragmentview;
}
private void getLocationDialog()
{
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
Task<LocationSettingsResponse> result =
LocationServices.getSettingsClient(getContext()).checkLocationSettings(builder.build());
result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>()
{
@Override
public void onComplete(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(),
REQUEST_CHECK_SETTINGS);
}
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;
}
}
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode)
{
case REQUEST_CHECK_SETTINGS:
switch (resultCode)
{
case Activity.RESULT_OK:
// All required changes were successfully made
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
break;
default:
break;
}
break;
}
}[enter image description here][2]
}
GoogleApiClient 已弃用。 Kotlin 中的新实现可以如下所示。
依赖项
// Google Maps Location Services
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
代码
val locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(30 * 1000)
.setFastestInterval(5 * 1000)
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
.setAlwaysShow(true)
val pendingResult = LocationServices
.getSettingsClient(activity)
.checkLocationSettings(builder.build())
pendingResult.addOnCompleteListener { task ->
if (task.isSuccessful.not()) {
task.exception?.let {
if (it is ApiException && it.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
(it as ResolvableApiException).startResolutionForResult(activity,
MainActivity.REQUEST_CODE_LOCATION)
}
}
}
}
设置 api 已弃用 this。
private void openDeviceLocationRequest() {
if (!locationPermissionGranted)
return;
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true); //this is the key ingredient
Task<LocationSettingsResponse> result =
LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
result.addOnCompleteListener(task -> {
try {
LocationSettingsResponse response = task.getResult(ApiException.class);
// All location settings are satisfied. The client can initialize location
// requests here.
if(lastKnownLocation == null)
getDeviceLocation();
} 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(
MapAddressActivity.this,
REQUEST_CHECK_SETTINGS);
} 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;
}
}
});
}
这是我的 Kotlin 示例-
private fun enableLocation() {
val locationRequest = LocationRequest.create()
locationRequest.apply {
priority =LocationRequest.PRIORITY_HIGH_ACCURACY
interval = 30 * 1000.toLong()
fastestInterval = 5 * 1000.toLong()
}
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
builder.setAlwaysShow(true)
val result=
LocationServices.getSettingsClient(requireContext()).checkLocationSettings(builder.build())
result.addOnCompleteListener {
try {
val response: LocationSettingsResponse = it.getResult(ApiException::class.java)
println("location>>>>>>> ${response.locationSettingsStates.isGpsPresent}")
if(response.locationSettingsStates.isGpsPresent)
//do something
}catch (e: ApiException){
when (e.statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
val intentSenderRequest =
IntentSenderRequest.Builder(e.status.resolution).build()
launcher.launch(intentSenderRequest)
} catch (e: IntentSender.SendIntentException) {
}
}
}
}
}
并使用下面的获取结果方法
private var launcher= registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()){ result->
if (result.resultCode == Activity.RESULT_OK) {
Log.d(TAG, "OK")
} else {
Log.d(TAG, "CANCEL")
requireContext().toast("Please Accept Location enable for use this App.")
}
}
实施'com.google.android.gms:play-services-location:18.0.0'
private SettingsClient mSettingsClient;
private LocationSettingsRequest mLocationSettingsRequest;
private static final int REQUEST_CHECK_SETTINGS = 214;
private static final int REQUEST_ENABLE_GPS = 516;
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(new LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
builder.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
mSettingsClient = LocationServices.getSettingsClient(MainActivity.this);
mSettingsClient
.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
//Success Perform Task Here
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.e("GPS","Unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e("GPS","Location settings are inadequate, and cannot be fixed here. Fix in Settings.");
}
}
})
.addOnCanceledListener(new OnCanceledListener() {
@Override
public void onCanceled() {
Log.e("GPS","checkLocationSettings -> onCanceled");
}
});
我使用最新版本的 Google Play Services (7.0) 并按照他们的指南中给出的步骤进行操作,我启用了如下所示的位置对话框,其中有一个 "never" 按钮。我的应用程序强制需要位置,所以我不想向用户显示 "never",因为一旦用户点击 "never",我就根本无法获取位置或再次请求位置。
因为 Google 地图只有是和没有按钮而没有从不按钮,知道如何实现相同的吗?
我的应用程序图片
Google 地图的图像
LocationSettingsRequest.Builder 有一个方法 setAlwaysShow(boolean show)
。 虽然文档表明它当前什么都不做(更新于 2015-07-05:更新的 Google 文档已删除此措辞),设置 builder.setAlwaysShow(true);
将启用 Google 地图行为:
这是让它工作的代码:
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).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); //this is the key ingredient
//**************************
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();
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(
getActivity(), 1000);
} 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;
}
}
});
}
对于 Kotlin,请参阅此处:
我想为那些正在寻找处理 Yes/No 按钮的人添加对 kai 的回答的一些更改。
在您的 activity
中声明此常量protected static final int REQUEST_CHECK_SETTINGS = 0x1;
在您的 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(MainActivity.this, REQUEST_CHECK_SETTINGS);
} 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;
}
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
settingsrequest();//keep asking if imp or do whatever
break;
}
break;
}
}
Ola Cabs 正在使用新发布的设置 API 来实现此功能。根据新的 API,用户无需导航至设置页面即可启用位置服务,从而实现无缝集成。请阅读以下内容了解更多详情:
https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi
它的工作方式类似于 google 地图?
源代码:https://drive.google.com/open?id=0BzBKpZ4nzNzUOXM2eEhHM3hOZk0
在 build.gradle 文件中添加依赖项:
compile 'com.google.android.gms:play-services:8.3.0'
或
compile 'com.google.android.gms:play-services-location:10.0.1'
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;
}
}
});
}
}
}
依赖关系
compile 'com.google.android.gms:play-services-location:10.0.1'
代码
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
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.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public static final int REQUEST_LOCATION=001;
GoogleApiClient googleApiClient;
LocationManager locationManager;
LocationRequest locationRequest;
LocationSettingsRequest.Builder locationSettingsRequest;
Context context;
PendingResult<LocationSettingsResult> pendingResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
Toast.makeText(this, "Gps is Enabled", Toast.LENGTH_SHORT).show();
} else {
mEnableGps();
}
}
public void mEnableGps() {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
mLocationSetting();
}
public void mLocationSetting() {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(1 * 1000);
locationRequest.setFastestInterval(1 * 1000);
locationSettingsRequest = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
mResult();
}
public void mResult() {
pendingResult = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, locationSettingsRequest.build());
pendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(@NonNull LocationSettingsResult locationSettingsResult) {
Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(MainActivity.this, REQUEST_LOCATION);
} catch (IntentSender.SendIntentException e) {
}
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;
}
}
});
}
//callback method
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case REQUEST_LOCATION:
switch (resultCode) {
case Activity.RESULT_OK:
// All required changes were successfully made
Toast.makeText(context, "Gps enabled", Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
Toast.makeText(context, "Gps Canceled", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
break;
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
您还可以为 Builder 添加多个 LocationRequests 以实现 "Use GPS, Wi-Fi and mobile networks for location" 对话框而不是 "Use GPS for location"
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY))
.addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_HIGH_ACCURACY))
.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
LocationServices.SettingsApi 现在已弃用,所以我们使用 SettingsClient
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10);
mLocationRequest.setSmallestDisplacement(10);
mLocationRequest.setFastestInterval(10);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new
LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
然后检查是否满足当前位置设置。 创建 LocationSettingsResponse 任务:
Task<LocationSettingsResponse> task=LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
然后添加监听器
task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() {
@Override
public void onComplete(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(
HomeActivity.this,
101);
} 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;
}
}
}
});
已添加 onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case 101:
switch (resultCode) {
case Activity.RESULT_OK:
// All required changes were successfully made
Toast.makeText(HomeActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show();
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
Toast.makeText(HomeActivity.this,"Canceled",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
break;
}
}
在 Kotlin 中,使用此代码:
import android.app.Activity
import android.content.Intent
import android.content.IntentSender
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.PendingResult
import com.google.android.gms.common.api.Status
import com.google.android.gms.location.*
class MainActivity : AppCompatActivity() {
private var googleApiClient: GoogleApiClient? = null
private val REQUESTLOCATION = 199
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableLoc()
}
private fun enableLoc() {
googleApiClient = GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks {
override fun onConnected(bundle: Bundle?) {}
override fun onConnectionSuspended(i: Int) {
googleApiClient?.connect()
}
})
.addOnConnectionFailedListener {
}.build()
googleApiClient?.connect()
val locationRequest = LocationRequest.create()
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationRequest.interval = 30 * 1000.toLong()
locationRequest.fastestInterval = 5 * 1000.toLong()
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 {
status.startResolutionForResult(
this@MainActivity,
REQUESTLOCATION
)
} catch (e: IntentSender.SendIntentException) {
}
}
}
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUESTLOCATION -> when (resultCode) {
Activity.RESULT_OK -> Log.d("abc","OK")
Activity.RESULT_CANCELED -> Log.d("abc","CANCEL")
}
}
}
}
请查看我在前台获取用户位置的非常简单的解决方案。
- GPS 设置对话框
- 具有实时数据的用户位置。
- LocationUtility class activity 生命周期感知 pause/resume 位置更新。
- 位置最新 FusedLocationProviderClient
2020 年 8 月新的更新答案 enter link description here
如果你在 activity
中使用,我的片段就像这个更新 import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
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.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
public class FragmentSearch extends Fragment
{
View SearchFragmentview;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
SearchFragmentview=inflater.inflate(R.layout.fragment_search,container,false);
getLocationDialog();
return SearchFragmentview;
}
private void getLocationDialog()
{
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
Task<LocationSettingsResponse> result =
LocationServices.getSettingsClient(getContext()).checkLocationSettings(builder.build());
result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>()
{
@Override
public void onComplete(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(),
REQUEST_CHECK_SETTINGS);
}
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;
}
}
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch (requestCode)
{
case REQUEST_CHECK_SETTINGS:
switch (resultCode)
{
case Activity.RESULT_OK:
// All required changes were successfully made
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
break;
default:
break;
}
break;
}
}[enter image description here][2]
}
GoogleApiClient 已弃用。 Kotlin 中的新实现可以如下所示。
依赖项
// Google Maps Location Services
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
代码
val locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(30 * 1000)
.setFastestInterval(5 * 1000)
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
.setAlwaysShow(true)
val pendingResult = LocationServices
.getSettingsClient(activity)
.checkLocationSettings(builder.build())
pendingResult.addOnCompleteListener { task ->
if (task.isSuccessful.not()) {
task.exception?.let {
if (it is ApiException && it.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
(it as ResolvableApiException).startResolutionForResult(activity,
MainActivity.REQUEST_CODE_LOCATION)
}
}
}
}
设置 api 已弃用 this。
private void openDeviceLocationRequest() {
if (!locationPermissionGranted)
return;
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true); //this is the key ingredient
Task<LocationSettingsResponse> result =
LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
result.addOnCompleteListener(task -> {
try {
LocationSettingsResponse response = task.getResult(ApiException.class);
// All location settings are satisfied. The client can initialize location
// requests here.
if(lastKnownLocation == null)
getDeviceLocation();
} 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(
MapAddressActivity.this,
REQUEST_CHECK_SETTINGS);
} 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;
}
}
});
}
这是我的 Kotlin 示例-
private fun enableLocation() {
val locationRequest = LocationRequest.create()
locationRequest.apply {
priority =LocationRequest.PRIORITY_HIGH_ACCURACY
interval = 30 * 1000.toLong()
fastestInterval = 5 * 1000.toLong()
}
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest)
builder.setAlwaysShow(true)
val result=
LocationServices.getSettingsClient(requireContext()).checkLocationSettings(builder.build())
result.addOnCompleteListener {
try {
val response: LocationSettingsResponse = it.getResult(ApiException::class.java)
println("location>>>>>>> ${response.locationSettingsStates.isGpsPresent}")
if(response.locationSettingsStates.isGpsPresent)
//do something
}catch (e: ApiException){
when (e.statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
val intentSenderRequest =
IntentSenderRequest.Builder(e.status.resolution).build()
launcher.launch(intentSenderRequest)
} catch (e: IntentSender.SendIntentException) {
}
}
}
}
}
并使用下面的获取结果方法
private var launcher= registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()){ result->
if (result.resultCode == Activity.RESULT_OK) {
Log.d(TAG, "OK")
} else {
Log.d(TAG, "CANCEL")
requireContext().toast("Please Accept Location enable for use this App.")
}
}
实施'com.google.android.gms:play-services-location:18.0.0'
private SettingsClient mSettingsClient;
private LocationSettingsRequest mLocationSettingsRequest;
private static final int REQUEST_CHECK_SETTINGS = 214;
private static final int REQUEST_ENABLE_GPS = 516;
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(new LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
builder.setAlwaysShow(true);
mLocationSettingsRequest = builder.build();
mSettingsClient = LocationServices.getSettingsClient(MainActivity.this);
mSettingsClient
.checkLocationSettings(mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
//Success Perform Task Here
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
ResolvableApiException rae = (ResolvableApiException) e;
rae.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sie) {
Log.e("GPS","Unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e("GPS","Location settings are inadequate, and cannot be fixed here. Fix in Settings.");
}
}
})
.addOnCanceledListener(new OnCanceledListener() {
@Override
public void onCanceled() {
Log.e("GPS","checkLocationSettings -> onCanceled");
}
});