我试图通过改变GPS的启用状态来触发从IntentService管理启动和停止位置更新(以及其他连接操作)。问题出现是因为GoogleApiClient上的.connect()方法是异步运行的,这使得服务能够死掉。当收到onConnected()的回调时,静态全局变量mGoogleApiClient已被擦除。对于removeLocationUpdates(),我得到:
java.lang.NullPointerException: GoogleApiClient must not be null
和requestLocationUpdates()我得到:
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
在IntentService的死亡和重生之间保留GoogleApiClient实例(这是请求和删除方法的必需参数)的正确方法是什么?或者,如果这是一个错误的问题,那么完成我想要做的事情的正确方法是什么?
编辑(19APR15): 以下是代码的相关部分......从我的课程中扩展了听取GPS事件的WakefulBroadcastReceiver:
public void onReceive(Context context, Intent intent) {
// If user enables or disables GPS
if(intent.getAction().equals(LocationManager.MODE_CHANGED_ACTION) || intent.getAction().equals(LocationManager.PROVIDERS_CHANGED_ACTION)) {
Intent mIntent = new Intent(context, ActivationIntentService.class);
mIntent.putExtra("enabled", isGPSEnabled(context));
startWakefulService(context, mIntent);
}
}
从ActivationIntentService类接收从startWakefulService传递的意图:
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
this.intent = intent;
if(intent.hasExtra("enabled")) {
if(intent.getBooleanExtra("enabled", false)) {
buildGoogleApiClient();
}
else {
stopUpdates();
}
}
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(ActivityRecognition.API)
.build();
mGoogleApiClient.connect();
}
protected LocationRequest getLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return mLocationRequest;
}
@Override
public void onConnected(Bundle bundle) {
startLocationUpdates();
startActivityRecognitionUpdates();
ActivationReceiver.completeWakefulIntent(intent);
}
public void stopUpdates() {
PendingIntent locationPendingIntent = PendingIntent.getService(this, 1, new Intent(this, LocationIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,locationPendingIntent);
PendingIntent activityRecognitionPendingIntent = PendingIntent.getService(this, 2, new Intent(this, ActivityRecognitionIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(mGoogleApiClient,activityRecognitionPendingIntent);
}
public void startLocationUpdates() {
PendingIntent locationPendingIntent = PendingIntent.getService(this, 1, new Intent(this, LocationIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, getLocationRequest(), locationPendingIntent);
}
public void startActivityRecognitionUpdates() {
PendingIntent activityRecognitionPendingIntent = PendingIntent.getService(this, 2, new Intent(this, ActivityRecognitionIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(mGoogleApiClient, 5000, activityRecognitionPendingIntent);
}
答案 0 :(得分:2)
我的第一个怀疑是正确的。我试图解决错误的问题。
通过跟踪几乎每个方法调用进行详细调试后,我意识到系统由于某种原因正在广播GPS模式更改两次,因此在第一次onConnected回调时已经实例化了第二个GoogleApiClient(覆盖了第一个实例)是从第一个.connect()调用中解雇的。正在使用第二个(未连接的)客户端变量而不是第一个用于启动或停止更新的方法,这导致抛出异常。由于系统每次触发两个广播,用户启用或禁用GPS(对我来说似乎有些愚蠢),我在BroadcastReceiver中设置了一个标志,以便我可以忽略第二个。解决了问题。