我的所有 FusedLocation 请求的列表
Posted
技术标签:
【中文标题】我的所有 FusedLocation 请求的列表【英文标题】:List of all my FusedLocation requests 【发布时间】:2017-12-05 15:58:14 【问题描述】:我正在使用下面的代码在一项活动中注册位置更新,但我如何检查我的应用程序之前是否已注册此请求(或查询我的活动位置请求)并且仍在等待对于位置响应,所以我不会提出重复请求?我可以关闭我的应用并再次运行它而不停止此请求:
this.locationRequest = new LocationRequest();
this.locationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
this.locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
this.locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(this.locationRequest);
this.locationSettingsRequest = builder.build();
this.locationCallback = new LocationCallback()
@Override
public void onLocationResult(LocationResult locationResult)
super.onLocationResult(locationResult); // why? this. is. crazy. android.
Location currentLocation = locationResult.getLastLocation();
GPSPoint gpsPoint = new GPSPoint(currentLocation.getLatitude(),
currentLocation.getLongitude());
Log.i(TAG, "Location Callback results: " + gpsPoint);
if (null != workable)
workable.work(gpsPoint);
;
this.mFusedLocationClient =
LocationServices.getFusedLocationProviderClient(MainApplication.getAppContext());
this.mFusedLocationClient.requestLocationUpdates(this.locationRequest,
this.locationCallback, Looper.myLooper());
【问题讨论】:
【参考方案1】:但是如何检查我的应用之前是否已注册此请求(或查询我的活动位置请求)并且仍在等待位置响应,因此我不会发出重复请求?
根据 [FusedLocationProvider API](https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener, android.os.Looper)) 的文档,
public abstract PendingResult<Status> requestLocationUpdates (GoogleApiClient client, LocationRequest request, LocationListener listener, Looper looper)
上面的代码可以:
为调用返回一个 PendingResult,检查
isSuccess()
以确定是否 成功了。
也许你可以尝试isSuccess()
来检查请求是否已经注册并应用验证,如果它抛出true
那么它应该已经停止发出另一个请求。
【讨论】:
【参考方案2】:public class BackgroundLocationService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
GpsStatus.Listener,
LocationListener
// Constants here....
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private LocationManager locationManager;
// Flag that indicates if a request is underway.
private boolean mInProgress;
private NotificationManagement myNotificationManager;
private Boolean servicesAvailable = false;
//And other variables here...
@Override
public void onCreate()
super.onCreate();
myNotificationManager = new NotificationManagement(getApplicationContext());
myNotificationManager.displayMainNotification();
mInProgress = false;
// Create the LocationRequest object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval
mLocationRequest.setInterval(PREFERRED_INTERVAL);
// Set the fastest update interval
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
servicesAvailable = servicesConnected();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.addGpsStatusListener(this);
setUpLocationClientIfNeeded();
/**
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
protected synchronized void buildGoogleApiClient()
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
private boolean servicesConnected()
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode)
return true;
else
return false;
public int onStartCommand(Intent intent, int flags, int startId)
super.onStartCommand(intent, flags, startId);
if (!servicesAvailable || mGoogleApiClient.isConnected() || mInProgress)
return START_STICKY;
setUpLocationClientIfNeeded();
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting() && !mInProgress)
mInProgress = true;
mGoogleApiClient.connect();
return START_STICKY;
private void setUpLocationClientIfNeeded()
if (mGoogleApiClient == null)
buildGoogleApiClient();
public void onGpsStatusChanged(int event)
// Define the callback method that receives location updates
@Override
public void onLocationChanged(Location location)
simpleGPSFilter(location);
// Other fancy and needed stuff here...
/**
* "Stupid" filter that utilizes experience data to filter out location noise.
* @param location Location object carrying all the needed information
*/
private void simpleGPSFilter(Location location)
//Loading all the required variables
int signalPower = 0;
satellites = 0;
// Getting the satellites
mGpsStatus = locationManager.getGpsStatus(mGpsStatus);
Iterable<GpsSatellite> sats = mGpsStatus.getSatellites();
if (sats != null)
for (GpsSatellite sat : sats)
if (sat.usedInFix())
satellites++;
signalPower += sat.getSnr();
if (satellites != 0)
signalPower = signalPower/satellites;
mySpeed = (location.getSpeed() * 3600) / 1000;
myAccuracy = location.getAccuracy();
myBearing = location.getBearing();
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.i("START OF CYCLE", "START OF CYCLE");
Log.i("Sat Strength", Integer.toString(signalPower));
Log.i("Locked Sats", Integer.toString(satellites));
// Do the math for the coordinates distance
/*
* Earth's radius at given Latitude.
* Formula: Radius = sqrt( ((equatorR^2 * cos(latitude))^2 + (poleR^2 * sin(latitude))^2 ) / ((equatorR * cos(latitude))^2 + (poleR * sin(latitude))^2)
* IMPORTANT: Math lib uses radians for the trigonometry equations so do not forget to use toRadians()
*/
Log.i("Lat for Radius", Double.toString(latitude));
double earthRadius = Math.sqrt((Math.pow((EARTH_RADIUS_EQUATOR * EARTH_RADIUS_EQUATOR * Math.cos(Math.toRadians(latitude))), 2)
+ Math.pow((EARTH_RADIUS_POLES * EARTH_RADIUS_POLES * Math.cos(Math.toRadians(latitude))), 2))
/ (Math.pow((EARTH_RADIUS_EQUATOR * Math.cos(Math.toRadians(latitude))), 2)
+ Math.pow((EARTH_RADIUS_POLES * Math.cos(Math.toRadians(latitude))), 2)));
Log.i("Earth Radius", Double.toString(earthRadius));
/*
* Calculating distance between 2 points on map using the Haversine formula (arctangent writing) with the following algorithm
* latDifference = latitude - lastLatitude;
* lngDifference = longitude - lastLongitude;
* a = (sin(latDifference/2))^2 + cos(lastLatitude) * cos(latitude) * (sin(lngDifference/2))^2
* c = 2 * atan2( sqrt(a), sqrt(1-a) )
* distance = earthRadius * c
*/
double latDifference = latitude - lastLatitude;
double lngDifference = longitude - lastLongitude;
double a = Math.pow((Math.sin(Math.toRadians(latDifference / 2))), 2) + (Math.cos(Math.toRadians(lastLatitude))
* Math.cos(Math.toRadians(latitude))
* Math.pow((Math.sin(Math.toRadians(lngDifference / 2))), 2));
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = earthRadius * c;
Log.i("New point distance", Double.toString(distance));
// Filter logic
// Make an initial location log
if ((!isInit) && (myAccuracy < ACCEPTED_ACCURACY))
isInit = true;
lastLatitude = latitude;
lastLongitude = longitude;
logLocations(location);
else
// Satellite lock (use of GPS) on the higher level
if (satellites == 0)
// Accuracy filtering at the second level
if (myAccuracy < ACCEPTED_ACCURACY)
if ((distance > ACCEPTED_DISTANCE))
lastLatitude = latitude;
lastLongitude = longitude;
logLocations(location);
Log.i("Location Logged", "No Sats");
/*
// Calculate speed in correlation to perceived movement
double speed = distance / (PREFERRED_INTERVAL / 1000); // TODO: Need to make actual time dynamic as the fused location does not have fixed timing
if (speed < ACCEPTED_SPEED)
lastLatitude = latitude;
lastLongitude = longitude;
logLocations(location);
*/
else if ((satellites < 4) && (signalPower > ACCEPTED_SIGNAL))
if (myAccuracy < (ACCEPTED_ACCURACY + 50))
logLocations(location);
Log.i("Location Logged", "With Sats");
else
if (myAccuracy < (ACCEPTED_ACCURACY + 100))
lastSpeed = mySpeed;
lastBearing = myBearing;
lastLatitude = latitude;
lastLongitude = longitude;
logLocations(location);
Log.i("Location Logged", "With Good Sats");
Log.i("END OF CYCLE", "END OF CYCLE");
private void logLocations(Location location)
String myprovider = "false";
String temp = timestampFormat.format(location.getTime());
mysqliteHelper dbHelper = new MySQLiteHelper(getApplicationContext());
try
dbHelper.createEntry(latitude, longitude, allschemes, temp, mySpeed, myAccuracy, myBearing, myprovider, satellites);
catch (Exception e)
e.printStackTrace();
CheckAutoArrive(String.valueOf(latitude), String.valueOf(longitude));
这可能以基本方式起作用,但如果您需要对这些内容进行详细说明,请访问我即将发布的有关 JAVA 中的融合位置的视频中的 YouTube 频道 Techzology。
【讨论】:
发布 250 多行代码而没有任何解释并不完全是 Stack Overflow 对答案的定义。以上是关于我的所有 FusedLocation 请求的列表的主要内容,如果未能解决你的问题,请参考以下文章
FusedLocation 不会触发 android api <= 21 的 locationcallback
fusedLocation API 间隔与关闭 GPS 无线电有何关系
FusedLocation GoogleApi - 侦听器不得为空 (Xamarin.Android)