我正在开发一款应用程序,如果用户位于特定区域内,该应用应能持续获得准确的用户位置。 位置更新应保存在服务器(Parse.com)上,以便其他用户可以获取用户的当前位置。
流程是:
问题:
我不确定如何实现第4步,我是否应该在onLocationChanged方法内的parse中保存新位置?我应该将它传递给BroadcastReciever并将其保存在那里解析吗?或者我应该将它传递给我的CurrentUser类中的静态方法,该方法将在服务器上执行保存?
我注意到requestLocationUpdates文档说:
"此方法适用于前台用例,更具体地说 用于在连接到LocationClient时请求位置。对于 后台用例,PendingIntent版本的方法是 。推荐"
在我的情况下,我应该使用哪种方法?
我应该使用什么值来获得几乎实时的位置而不会每小时消耗超过5%的电池电量?
我的服务类:
public class UserTracker extends Service implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, LocationListener{
static int GEOFENCE_STATUS;
final static int INSIDE_GEOFENCE = 9001, OUTSIDE_GEOFENCE = 9002;
static final int MINIMUM_ACCURACY = 26;
final static int GEOFENCE_RADIUS = 2000;
static final int NULL_LOCATION_ERROR = 7001;
static final int INSIDE_INTERVAL = 10000, INSIDE_FASTEST_INTERVAL = 1000, INSIDE_SMALLEST_DISPLACEMENT = 10;
static final int OUTSIDE_INTERVAL = 300000, OUTSIDE_FASTEST_INTERVAL = 60000, OUTSIDE_SMALLEST_DISPLACEMENT = 100;
static Location eventLocation;
LocationClient lc;
@Override
public void onCreate() {
super.onCreate();
eventLocation = new Location("Test");
lc = new LocationClient(getApplicationContext(), this, this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
double eventLat = intent.getDoubleExtra("Latitude", -1);
double eventLon = intent.getDoubleExtra("Longitude", -1);
if (eventLat == -1 || eventLon == -1) {
stopSelf();
return START_REDELIVER_INTENT;
}
eventLocation.setLatitude(eventLat);
eventLocation.setLongitude(eventLon);
lc.connect();
return START_STICKY;
}
public int getGeofenceStatus(Location currentLocation) {
if (currentLocation == null) {
return NULL_LOCATION_ERROR;
}
if (currentLocation.distanceTo(eventLocation) > GEOFENCE_RADIUS) {
Log.d(TAG, "User is outside geofence");
return OUTSIDE_GEOFENCE;
} else {
Log.d(TAG, "User is inside geofence");
return INSIDE_GEOFENCE;
}
}
public void requestLocationUpdates(int status) {
GEOFENCE_STATUS = status;
LocationRequest request = LocationRequest.create();
switch (status) {
case NULL_LOCATION_ERROR:
stopSelf();
break;
case INSIDE_GEOFENCE:
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
request.setInterval(INSIDE_INTERVAL);
request.setFastestInterval(INSIDE_FASTEST_INTERVAL);
request.setSmallestDisplacement(INSIDE_SMALLEST_DISPLACEMENT);
break;
case OUTSIDE_GEOFENCE:
request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
request.setInterval(OUTSIDE_INTERVAL);
request.setFastestInterval(OUTSIDE_FASTEST_INTERVAL);
request.setSmallestDisplacement(OUTSIDE_SMALLEST_DISPLACEMENT);
break;
}
lc.requestLocationUpdates(request, this);
}
@Override
public void onLocationChanged(Location location) {
int newStatus = getGeofenceStatus(location);
int accuracy = (int) location.getAccuracy();
String message = "Geofence status: " + newStatus +
"\nAccuracy: " + accuracy +
"\nDistance to event: " + location.distanceTo(eventLocation);
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
if (newStatus == INSIDE_GEOFENCE && accuracy < MINIMUM_ACCURACY) {
Log.d(TAG, "Accuracy is good");
// do the save on server procees
}
if (GEOFENCE_STATUS != newStatus) {
requestLocationUpdates(newStatus);
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.d(TAG, "LocationClient connection failed: " + result.getErrorCode());
}
@Override
public void onConnected(Bundle arg0) {
Location currentLocation = lc.getLastLocation();
requestLocationUpdates(getGeofenceStatus(currentLocation));
}
@Override
public void onDisconnected() {
Log.d(TAG, "LocationClient disconnected");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}