"GoogleApiClient is not connected yet"意图服务中的错误



我正在创建一个应用程序,使用IntentService中的AlarmManagerGoogleAPIClient的帮助下每30分钟检查用户的位置。

onHandleIntent()在我的服务中触发时,我得到这个错误:

FATAL EXCEPTION: IntentService[FindLocationService]
Process: ir.imanirt.remindmeathome, PID: 1382
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.internal.zzqb.zzd(Unknown Source)
at com.google.android.gms.internal.zzqf.zzd(Unknown Source)
at com.google.android.gms.internal.zzqd.zzd(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at ir.imanirt.remindmeathome.FindLocationService.getCurrentLocation(FindLocationService.java:122)
at ir.imanirt.remindmeathome.FindLocationService.onHandleIntent(FindLocationService.java:105)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)

这是我的FindLocationService.java类:

import android.Manifest;
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class FindLocationService extends IntentService {
    private static final String TAG = "FINDLOCATIONSERVICE";
    private static final int SERVICE_REQUEST_CODE = 101;
    private GoogleApiClient mClient;
    private NotificationCompat.Builder mNotificationBuilder;
    public FindLocationService() {
        super(FindLocationService.class.getName());
    }
    public static Intent newIntent(Context context) {
        return new Intent(context, FindLocationService.class);
    }
    public static boolean isServiceAlarmOn(Context context) {
        Intent i = FindLocationService.newIntent(context);
        PendingIntent pendingIntent = PendingIntent
                .getService(context, SERVICE_REQUEST_CODE, i, PendingIntent.FLAG_NO_CREATE);
        return pendingIntent != null;
    }
    public static void setServiceAlarm(Context context, boolean isOn) {
        final int GPS_TIME = 1000 * 60; //every 1 minute (for the sake of testing)
        Intent i = FindLocationService.newIntent(context);
        PendingIntent pendingIntent = PendingIntent.getService(context, SERVICE_REQUEST_CODE, i, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        if (isOn) {
            alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
                    SystemClock.elapsedRealtime(), GPS_TIME, pendingIntent);
        } else {
            alarmManager.cancel(pendingIntent);
            pendingIntent.cancel();
        }
    }
    @Override
    public void onDestroy() {
        mClient.disconnect();
        super.onDestroy();
    }
    @Override
    public void onCreate() {
        super.onCreate();
        mNotificationBuilder = new NotificationCompat.Builder(this);
        mNotificationBuilder.setSmallIcon(android.R.drawable.star_on);
        mNotificationBuilder.setContentTitle("Got a Location!!");   //set properties for notification
        mClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                    @Override
                    public void onConnected(@Nullable Bundle bundle) {
                        Log.d(TAG, "Connected to Google location API");
                    }
                    @Override
                    public void onConnectionSuspended(int i) {
                    }
                })
                .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                        Log.d(TAG, "Failed to connect to Google API");
                    }
                })
                .build();
        mClient.connect();
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        getCurrentLocation();
    }
    private void getCurrentLocation() {
        LocationRequest request = new LocationRequest();
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        request.setNumUpdates(1);
        request.setInterval(0);
        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Location permission denied.");
            return;
        }
        //I believe this is the line that causes the error:
        LocationServices.FusedLocationApi.requestLocationUpdates(mClient, request, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                Log.d(TAG, "Got a location fix: " + location);
                //Notify user about the new location
                mNotificationBuilder.setContentText("Location is " + location);
                NotificationManager mNotificationManager = (NotificationManager)
                        getSystemService(Context.NOTIFICATION_SERVICE);
                mNotificationManager.notify(1, mNotificationBuilder.build());
            }
        });
    }
}

另外,在我的片段中有一个按钮,它调用setServiceAlarm来打开警报管理器。

如错误所示,当onHandleIntent启动时,我的GoogleAPIClient实例(mClient)未连接。我把mClient.connect()onHandleIntent,但它仍然不起作用。我不明白为什么?我是否使用了错误的逻辑来编写代码?我应该把我的客户端构建器或我的mClient.connect()方法在其他地方吗?

Google建议在执行任何GPS相关活动之前检查GoogleApiClient.isConnected()

https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient.html与()

还可以添加回调https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks

并执行您的操作onConnected(Bundle connectionHint)

我想我找到问题了;mClient连接到google服务需要一些时间,因此getCurrentLocation()必须在mClient连接时执行。感谢@Maxim Berezovsky的回答,我添加了一个onConnected(Bundle bundle)回调来解决这个问题,但这引发了另一个问题:onHandleIntent()退出的速度比mClient可以连接的速度快,所以服务在mClient连接之前被杀死。为了解决这个问题,我在我的服务中使用了以下代码:

@Override
    public void onDestroy() {
        if (mClient.isConnected())
            mClient.disconnect();
        super.onDestroy();
    }

这将确保即使服务被杀死,mClient也不会断开连接。

我不确定这种方法是否耗电,但这是目前为止我得到的最好的方法。

相关内容

  • 没有找到相关文章