Android 融合位置更新
Posted
技术标签:
【中文标题】Android 融合位置更新【英文标题】:Android Fused Location Update 【发布时间】:2019-10-26 20:08:55 【问题描述】:我正在开发一个 android 应用程序,我正在通过 Fused Location 获取设备当前位置。
我正在检查用户是否具有授予权限,如果是,我正在获取位置,但如果用户没有授予权限,我正在打开权限对话框并且用户单击允许,然后谷歌显示以下对话框:
我应该如何处理此对话框单击事件,因为如果用户单击“确定”但它没有获取设备位置或者我没有收到任何位置更新回调,会发生什么?我希望当用户单击“确定”时它应该获取位置。 我应该如何做到这一点?
【问题讨论】:
How to show enable location dialog like Google maps?的可能重复 位置设置弹窗会通过调用onActivityResult()给出回调结果,所以必须在activity中实现onActivityResult。例如参考 (developers.google.com/android/reference/com/google/android/gms/…)。 【参考方案1】: publi void myLocationButtonClicked()
GpsLocationTracker mGpsLocationTracker = new GpsLocationTracker(activity);
if (mGpsLocationTracker.canGetLocation())
latitude = mGpsLocationTracker.getLatitude();
longitude = mGpsLocationTracker.getLongitude();
if ((latitude != 0 && longitude != 0)
else
showLocationSnackBar(activity.getString(R.string.wait));
else
locationChecker();
// this function to show dialog to open GPS if it is closed
public void locationChecker()
LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
SettingsClient client = LocationServices.getSettingsClient(activity);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(activity, locationSettingsResponse -> myLocationButtonClicked());
task.addOnFailureListener(activity, e ->
if (e instanceof ResolvableApiException)
// Location settings are not satisfied, but this can be fixed
// by showing the user a dialog.
try
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(activity,
REQUEST_GPS_RESULT_CODE_FOR_MAP_LOCATION);
catch (IntentSender.SendIntentException sendEx)
// Ignore the error.
);
这是用于获取用户位置的GpsLocationTracker
类
public class GpsLocationTracker extends Service implements LocationListener
/**
* min distance change to get location update
*/
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATE = 10;
/**
* min time for location update
* 60000 = 1min
*/
private static final long MIN_TIME_FOR_UPDATE = 60000;
/**
* context of calling class
*/
private Context mContext;
/**
* flag for gps status
*/
private boolean isGpsEnabled = false;
/**
* flag for network status
*/
private boolean isNetworkEnabled = false;
/**
* flag for gps
*/
private boolean canGetLocation = false;
/**
* location
*/
private Location mLocation;
/**
* latitude
*/
private double mLatitude;
/**
* longitude
*/
private double mLongitude;
/**
* location manager
*/
private LocationManager mLocationManager;
/**
* @param mContext constructor of the class
*/
public GpsLocationTracker(Context mContext)
this.mContext = mContext;
getLocation();
/**
* @return location
*/
public Location getLocation()
try
mLocationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
/*getting status of the gps*/
isGpsEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
/*getting status of network provider*/
isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGpsEnabled && !isNetworkEnabled)
/*no location provider enabled*/
else
this.canGetLocation = true;
/*getting location from network provider*/
if (isNetworkEnabled)
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_FOR_UPDATE, MIN_DISTANCE_CHANGE_FOR_UPDATE, this);
if (mLocationManager != null)
mLocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (mLocation != null)
mLatitude = mLocation.getLatitude();
mLongitude = mLocation.getLongitude();
/*if gps is enabled then get location using gps*/
if (isGpsEnabled)
if (mLocation == null)
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_FOR_UPDATE, MIN_DISTANCE_CHANGE_FOR_UPDATE, this);
if (mLocationManager != null)
mLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (mLocation != null)
mLatitude = mLocation.getLatitude();
mLongitude = mLocation.getLongitude();
catch (Exception e)
e.printStackTrace();
return mLocation;
/**
* call this function to stop using gps in your application
*/
public void stopUsingGps()
if (mLocationManager != null)
mLocationManager.removeUpdates(GpsLocationTracker.this);
/**
* @return latitude
* <p/>
* function to get latitude
*/
public double getLatitude()
if (mLocation != null)
mLatitude = mLocation.getLatitude();
return mLatitude;
/**
* @return longitude
* function to get longitude
*/
public double getLongitude()
if (mLocation != null)
mLongitude = mLocation.getLongitude();
return mLongitude;
/**
* @return to check gps or wifi is enabled or not
*/
public boolean canGetLocation()
return this.canGetLocation;
/**
* function to prompt user to open
* settings to enable gps
*/
public void showSettingsAlert()
AlertDialog.Builder mAlertDialog = new AlertDialog.Builder(new ContextThemeWrapper(mContext, R.style.AppTheme));
mAlertDialog.setTitle(R.string.gps_disabled);
mAlertDialog.setMessage(R.string.enable_gps);
mAlertDialog.setPositiveButton(R.string.settings, new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
Intent mIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(mIntent);
);
mAlertDialog.setNegativeButton(R.string.dialog_button_cancel, new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
dialog.cancel();
);
final AlertDialog mcreateDialog = mAlertDialog.create();
mcreateDialog.show();
@Override
public IBinder onBind(Intent arg0)
// TODO Auto-generated method stub
return null;
public void onLocationChanged(Location location)
// TODO Auto-generated method stub
public void onProviderDisabled(String provider)
// TODO Auto-generated method stub
public void onProviderEnabled(String provider)
// TODO Auto-generated method stub
public void onStatusChanged(String provider, int status, Bundle extras)
// TODO Auto-generated method stub
当用户点击确定按钮时,您必须检查onActivityResult()
中的结果。
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_GPS_RESULT_CODE_FOR_MAP_LOCATION && resultCode == RESULT_OK)
myLocationButtonClicked();
【讨论】:
但是当@Harsh Shah 问问题时,确定按钮点击监听器在哪里......你能解释一下你的答案吗 我也在做同样的事情,但我没有收到任何 onActivityResult 回调 你是在活动还是片段? 我认为我们无法处理此对话框确定按钮单击,因为它在内部仅启用您的 GPS,但单击确定按钮后,您会获得一个状态代码,我正在共享答案,请在该代码中尝试这个如果 gsp 启用或未维护状态代码,我将处理状态代码让我分享... @HiteshKushwah 好的。等待您的答复【参考方案2】:尝试此函数在按钮单击列表器上调用此函数并禁用您的 gps.. 当您单击按钮时,将出现 gps 对话框并启用 gps,当您再次单击按钮时,toast 将通过状态代码显示该句柄
private void EnableGPSAutoMatically()
GoogleApiClient googleApiClient = null;
if (googleApiClient == null)
googleApiClient = new GoogleApiClient.Builder(this)
.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:
toast("Success");
isgpson = true;
// All location settings are satisfied. The client can
// initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// toast("GPS is not on");
isgpson = false;
// 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(Activity_Splash.this, 1000);
catch (IntentSender.SendIntentException e)
// Ignore the error.
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// toast("Setting change not allowed");
// Location settings are not satisfied. However, we have
// no way to fix the
// settings so we won't show the dialog.
break;
);
【讨论】:
以上是关于Android 融合位置更新的主要内容,如果未能解决你的问题,请参考以下文章