我目前正在开发一个应用程序,该应用程序必须每五分钟检查一次用户的位置并将坐标发送到服务器。我决定使用 Google Play 服务中的 FusedLocation API 而不是普通的旧 LocationManager API,主要是因为我注意到LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY优先级,它声称提供 100 米精度级别和合理的电池使用,这正是我需要。
就我而言,我有一个 Activity,其继承结构是:
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener
并实现了相关的回调(onConnected、onConnectionFailed、onConnectionSuspended、onLocationChanged)。根据官方文档的建议,我还使用此方法获得了 GoogleApiClient 的实例:
protected synchronized GoogleApiClient buildGoogleApiClient() {
return new GoogleApiClient.Builder(this).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
在 onConnected 中,我使用
LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient,
mLocationRequest, this);
...并捕获 onLocationChanged() 中的更改。
但是,我很快发现位置更新似乎在一段时间后停止了。也许是因为这个方法与 Activity 生命周期相关,我不确定。无论如何,我试图通过创建一个扩展 IntentService 的内部类并通过 AlarmManager 启动它来解决这个问题。所以在 onConnected 中,我最终这样做了:
AlarmManager alarmMan = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
Intent updateIntent = new Intent(this, LocUpService.class);
PendingIntent pIntent = PendingIntent.getService(this, 0, updateIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmMan.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0,
1000 * 60 * 5, pIntent);
LocUpService 类如下所示:
public static class LocUpService extends IntentService {
public LocUpService() {
super("LocUpService");
}
@Override
protected void onHandleIntent(Intent intent) {
Coords coords = LocationUpdater.getLastKnownLocation(mApiClient);
}
}
LocationUpdater 是另一个类,它包含静态方法 getLastKnownLocation,它是这样的:
public static Coords getLastKnownLocation(GoogleApiClient apiClient) {
Coords coords = new Coords();
Location location = LocationServices.FusedLocationApi
.getLastLocation(apiClient);
if (location != null) {
coords.setLatitude(location.getLatitude());
coords.setLongitude(location.getLongitude());
Log.e("lat ", location.getLatitude() + " degrees");
Log.e("lon ", location.getLongitude() + " degrees");
}
return coords;
}
但是惊喜!!当我清楚地将引用传递给静态方法时,我得到“IllegalArgumentException:需要 GoogleApiClient 参数”,我再次猜测这肯定与 GoogleApiClient 实例与 Activity 的生命周期有关,并且将实例传递到意图服务。
所以我在想:我怎样才能在不发疯的情况下每五分钟定期更新一次位置?我是否扩展服务,在该组件上实现所有接口回调,在其中构建 GoogleApiClient 实例并使其在后台运行?我是否有一个 AlarmManager 启动一个服务,该服务每五分钟扩展一次 IntentService 来完成工作,再次在 IntentService 中构造所有相关的回调和 GoogleApiClient?我是否继续做我现在正在做的事情,但将 GoogleApiClient 构建为单例,期望它会有所作为?你会怎么做?
感谢和抱歉这么冗长。