Google API 客户端错误,发送位置
Posted
技术标签:
【中文标题】Google API 客户端错误,发送位置【英文标题】:Google API client bug, sending locations 【发布时间】:2015-08-14 05:53:12 【问题描述】:我想创建每隔几秒钟向 GCM 发送一条消息。但一段时间后,我想再次删除位置更新。为了将数据发送到 gcm 的意图服务,我使用了一个挂起的意图。现在每次都发生了很多我得到这个错误:
原因:
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.internal.n.a(Unknown Source)
at com.google.android.gms.common.api.b.b(Unknown Source)
at com.google.android.gms.internal.lt.removeLocationUpdates(Unknown Source)
at com.example.task_1.Location.LocationUpdate.stopLocationUpdates(LocationUpdate.java:83)
at com.example.task_1.Location.LocationUpdate.onStartCommand(LocationUpdate.java:52)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2704)
at android.app.ActivityThread.access$1900(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1353)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
这是我的代码:
public class LocationUpdate extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
private static final String TAG = "DRIVER";
private SharedPreferences pref;
private String driverId;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Intent mGcmIntentService;
private PendingIntent mPendingIntent;
@Override
public IBinder onBind(Intent arg0)
return null;
@Override
public int onStartCommand(Intent intent, int flags, int startId)
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
boolean stopService = false;
if (intent != null)
stopService = intent.getBooleanExtra("stopservice", false);
if (stopService)
stopLocationUpdates();
return START_STICKY;
@Override
public void onCreate()
Log.e(TAG, "onCreate");
pref = getSharedPreferences("driver_app", MODE_PRIVATE);
driverId = pref.getString("driver_id", "");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
@Override
public void onDestroy()
Log.e(TAG, "onDestroy");
super.onDestroy();
public void stopLocationUpdates()
if(!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
mGcmIntentService = new Intent(this,SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
if (mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
@Override
public void onConnectionFailed(ConnectionResult arg0)
// TODO Auto-generated method stub
@Override
public void onConnected(Bundle arg0)
// TODO Auto-generated method stub
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(30000);
startLocationUpdates();
private void startLocationUpdates()
mGcmIntentService = new Intent(this,SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
@Override
public void onConnectionSuspended(int arg0)
// TODO Auto-generated method stub
有人知道如何解决这个错误吗?或者如何解决?我在互联网上搜索,但找不到任何东西。
【问题讨论】:
我现在在打电话,所以看不到线路号码。但是在代码的第 83 行,客户端没有连接。查看阻塞直到有连接(不要阻塞 ui 线程) 你能说得更具体些吗,我要如何检查直到有连接?实现一个while循环?或者你能给我一个更好的解决方案吗? 【参考方案1】:问题是在您的stopLocationUpdates()
方法中,您在调用removeLocationUpdates()
之前没有等待API 连接。
解决此问题的一种简单方法是在您需要删除位置回调但 API 未连接时设置一个布尔标志。
添加成员变量:
private boolean isRemoving = false;
然后修改逻辑,使其在取消注册位置回调之前等待 API 连接。
在stopLocationUpdates()
方法中:
public void stopLocationUpdates()
if(!mGoogleApiClient.isConnected())
isRemoving = true; //added
mGoogleApiClient.connect();
else
mGcmIntentService = new Intent(this, SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mPendingIntent);
if (mGoogleApiClient.isConnected())
mGoogleApiClient.disconnect();
在onConnected()
回调中:
@Override
public void onConnected(Bundle arg0)
if (isRemoving)
stopLocationUpdates();
else
// TODO Auto-generated method stub
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(30000);
startLocationUpdates();
您还希望在 startLocationUpdates()
中将标志设置回 false:
private void startLocationUpdates()
isRemoving = false; //added
mGcmIntentService = new Intent(this,SendDataIntentService.class);
mGcmIntentService.putExtra("ID", "FusedLocation");
mPendingIntent = PendingIntent.getService(this, 0, mGcmIntentService, PendingIntent.FLAG_CANCEL_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mPendingIntent);
也在onCreate()
:
@Override
public void onCreate()
Log.e(TAG, "onCreate");
isRemoving = false; //added
pref = getSharedPreferences("driver_app", MODE_PRIVATE);
driverId = pref.getString("driver_id", "");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
编辑:要在之前取消后重新启动位置回调,您可以使用onStartCommand()
方法。
修改onStartCommand()
,使其可以停止和启动位置更新:
@Override
public int onStartCommand(Intent intent, int flags, int startId)
Log.e(TAG, "onStartCommand");
super.onStartCommand(intent, flags, startId);
boolean stopService = false;
if (intent != null)
stopService = intent.getBooleanExtra("stopservice", false);
if (stopService)
stopLocationUpdates();
else
isRemoving = false;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
return START_STICKY;
然后,为了重新开始位置更新,您将调用 startService()
并使用将 stopservice
设置为 false 的 Intent:
Intent i = new Intent(this, LocationUpdate.class);
i.putExtra("stopservice", false);
startService(i);
【讨论】:
它仍然给了我一些错误......我不知道为什么,但有时它工作有时不。当用户单击 UI 上的按钮时,我会启动和停止它。 当我第一次调用它时,位置已发送。然后我删除它们,然后当我想发回位置时,不再调用 oncreate 和 onconnected。 @TimDirks 我刚刚更新了答案,让我知道这是否适合你! 感谢您的快速回放,您是否知道如果我填写 900 000 的时间间隔(意味着每 15 分钟发送一次数据),但它每 4 分钟发送一次数据?我需要包含更具体的内容吗? @TimDirks 当然,没问题!如果我理解正确,听起来您应该在您的LocationRequest
中使用setFastestInterval()
方法。来自文档:If you don't call this method, a fastest interval will be selected for you. It will be a value faster than your active interval
在此处查看文档:developers.google.com/android/reference/com/google/android/gms/… 示例:***.com/questions/30191047/…以上是关于Google API 客户端错误,发送位置的主要内容,如果未能解决你的问题,请参考以下文章
Google BigQuery 和 Google API 客户端包
不是来自 Google API Oauth 的客户端的有效来源
使用nodejs客户端库将图像作为base64编码发送到google云视觉API