我正在为我的应用程序开发一项功能,该功能应该记录用户在后台的位置,并在稍后的某个时间点将其发送到服务器(将其视为一个简单的GPS跟踪器)。
我正在使用FusedLocationApi并通过待定意图请求位置传递。
当我开始进行位置跟踪时,我确实会将位置广播传送到我的应用程序,因此事情似乎正常。然而,当我长时间测试应用程序时,事情开始变得奇怪:
1)当我在办公室并且我的设备连接到Wi-Fi时,似乎位置传送很好。这些地点准确无误,所提供的坐标差异很小(手机放在我的桌子上):
19:28:29.276 [main] Location acquired, lat=53.9265544, lon=27.6993057
19:28:59.944 [main] Location acquired, lat=53.9265669, lon=27.6991762
19:29:30.884 [main] Location acquired, lat=53.9265529, lon=27.6992383
2)当我开车离开办公室并且我的测试手机与Wi-Fi断开连接时,位置仍在交付,但它始终是相同的坐标(靠近我的办公室)。我在高速公路上行驶时记录下面的日志(所有坐标都相同):
19:54:37.341 Location acquired, lat=53.9323538, lon=27.6920177
19:59:37.385 Location acquired, lat=53.9323538, lon=27.6920177
20:04:37.499 Location acquired, lat=53.9323538, lon=27.6920177
3)过了一会儿(我还在外面),地点广播的发送完全停止。
4)当我回到家(并且手机连接到WiFi)时,位置广播传送将恢复,并且正确的位置正在传送。
我在两台设备上试过这个:Nexus 7" 2013年& Prestigio PAP 5500的行为一般都是一样的。当我远离Wi-Fi时,似乎没有正确传送位置。当然,GPS模块已打开(两个设备)。
以下是我的代码供参考。 LocationManager类驻留在我的测试期间一直运行的服务中(从日志中可以看出)。
感谢任何帮助。
public class LocationManager extends BroadcastReceiver implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static LocationManager mInstance = null;
private GoogleApiClient mGoogleApiClient;
private PendingIntent locationReceivedPendingIntent;
public static LocationManager instance() {
if (mInstance == null) {
mInstance = new LocationManager();
}
return mInstance;
}
private LocationManager() {
mLog = LoggingManager.getLogger(getClass());
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(TimeDoctorApplication.context())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TimeTrackingModel.TASK_CHANGED);
LocalBroadcastManager.getInstance(TimeDoctorApplication.context()).registerReceiver(this, intentFilter);
locationReceivedPendingIntent = PendingIntent.getBroadcast(TimeDoctorApplication.instance().getApplicationContext(), 0, new Intent(LOCATION_RECEIVED), 0);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
boolean noFLPermission = ActivityCompat.checkSelfPermission(TimeDoctorApplication.context(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED;
boolean noCLPermission = ActivityCompat.checkSelfPermission(TimeDoctorApplication.context(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED;
if (noCLPermission || noFLPermission) {
return;
}
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(5 * 60 * 1000);
locationRequest.setFastestInterval(5 * 60 * 1000);
locationRequest.setMaxWaitTime(5 * 60 * 1000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, locationReceivedPendingIntent);
}
@Override
public void onConnectionSuspended(int i) {}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {}
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case SOME_EXTERNAL_EVENT:
int servicesAvailable = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(TimeDoctorApplication.context());
if (servicesAvailable != ConnectionResult.SUCCESS) {
GoogleApiAvailability.getInstance().showErrorNotification(TimeDoctorApplication.context(), servicesAvailable);
return;
}
if (NEEDS_TRACKING) {
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
} else {
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
break;
default:
break;
}
}
protected void recordLocation(Location l) {
//Processing location here
}
public static final String LOCATION_RECEIVED = "com.myapp.LOCATION_RECEIVED";
public static class LocationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra("com.google.android.location.LOCATION")) {
LocationManager.instance().recordLocation((Location) intent.getExtras().get("com.google.android.location.LOCATION"));
}
}
}
}