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 客户端包

android中需要google api客户端参数

不是来自 Google API Oauth 的客户端的有效来源

使用nodejs客户端库将图像作为base64编码发送到google云视觉API

需要Google OAuth 2.0架构建议通过Java邮件Api发送Smtp邮件

如果没有更新 Google Play 服务,如何处理 Google API 客户端