GoogleApiClient的onConnected方法没有被调用,在Service中使用。

8

我曾在Activity中使用GoogleApiClient时工作正常,但现在将其移到Service中后,onConnected未被调用。

public class StepsMonitoringService extends Service implements GoogleApiClient.ConnectionCallbacks {

private GoogleApiClient mClient;

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

@Override 
public void onCreate() {
    super.onCreate();
    mClient = new GoogleApiClient.Builder(this).addApi(Fitness.HISTORY_API)
            .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
            .addConnectionCallbacks(this).build();
    mClient.connect();  
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    return START_STICKY;    
}

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

@Override
public void onConnected(Bundle connectionHint) {
   // NOT being called!! WHY??
}

@Override
public void onConnectionSuspended(int cause) {
}

有人有什么想法吗?我做错了什么?有人在服务中使用过GoogleApiClient吗?

该服务从一个Activity中调用。

public class MainActivity extends FragmentActivity {

private TextView mStepsView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Intent intent = new Intent(this, StepsMonitoringService.class);
    startService(intent);

    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("StepMonitoringServiceIntent"));

    mStepsView = (TextView) findViewById(R.id.steps);
}

private void displayOnUI(String msg) {
    mStepsView.setText(msg + "\n" + mStepsView.getText());
}

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        long steps = intent.getLongExtra("steps", 0);
        displayOnUI(steps + " steps");
    }
};

在调试过程中,我可以看到Service的onCreate被调用了,但是onConnected没有被调用。根据日志来看,似乎没有什么特别之处。

你能展示一下如何启动服务吗?同时检查一下日志中是否有任何错误。 - Daniel Nugent
4个回答

10

首先需要实现以下接口:

  1. GoogleApiClient.ConnectionCallbacks
  2. GoogleApiClient.OnConnectionFailedListener

接着,你需要在你的类中添加以下方法:

  1. public void onConnected(final Bundle bundle)
  2. public void onConnectionSuspended(final int i)
  3. public void onConnectionFailed(final ConnectionResult connectionResult)

一旦连接成功,将会调用OnConnected方法。在此方法中,你可以执行任何你想做的事情,如获取当前位置、位置地址、向地图添加标记点等等。

但是,在没有连接到Google API客户端之前,你无法进行任何操作。 要连接到GoogleAPIClient,你可以在你的类中添加此方法,并在你的onCreate方法中调用它。

private synchronized void buildGoogleAPIClient(){
    googleApiclient = new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    googleApiclient.connect();
    Toast.makeText(getActivity(), "connected", Toast.LENGTH_SHORT).show();
}

2
点赞。忘记添加googleApiclient.connect(); 这就是原因,如此微小的原因。 - CodeToLife

2
addOnConnectionFailedListener添加到GoogleApiClient以跟踪错误。根据文档addOnConnectionFailedListener在客户端连接服务时发生错误时调用。
public class StepsMonitoringService extends Service implements GoogleApiClient.ConnectionCallbacks {

    private GoogleApiClient mClient;

    @Override 
    public void onCreate() {
        super.onCreate();
        mClient = new GoogleApiClient.Builder(this).addApi(Fitness.HISTORY_API)
            .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
            .addConnectionCallbacks(this)
            //Add Connection Failed Listener to track error.
            .addOnConnectionFailedListener(this)
            .build();
        mClient.connect();  
    }

    @Override
    public void onConnected(Bundle connectionHint) {
       // NOT being called!! WHY??
    }

    @Override
    public void onConnectionSuspended(int cause) {
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
         //Called called when there was an error connecting the client to the service. 
        Log.i(LOG_TAG,"onConnectionFailed:"+connectionResult.getErrorCode()+","+connectionResult.getErrorMessage());
    }
}

啊,我想是因为我在另一台电脑上工作,所以开发者证书与我用来激活Google健身API的不同。我会尝试一下。 - rukiman
根据文档,错误代码4表示客户端尝试连接服务,但用户未登录。 - Dhaval Patel
我该如何修复这个错误?我已经使用我的debug.keystore的SHA1创建了一个OAuth客户端ID。但我仍然收到相同的错误。 - rukiman
您需要在活动中连接到“Fitness”API一次,以便用户可以使用所需的Google帐户进行登录。 - Dhaval Patel
尝试过了,但没有运气 :( - rukiman
显示剩余4条评论

0
当我使用useDefaultAccount()创建客户端时,我遇到了同样的问题。然后我将其替换为setAccountName(),然后它开始起作用了。我认为出于某些原因,帐户选择器在服务中不起作用,这就是为什么googleapiclient的connect()无声失败的原因,因为您需要指定用于检索健身信息的帐户。请注意,在活动中需要有一个帐户选择器,并以某种方式将电子邮件帐户传递给您的服务。

0

试一下这个。

public class StepsMonitoringService extends Service implements
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {

    /**
     * Provides the entry point to Google Play services.
     */
    protected GoogleApiClient mClient;

    /**
     * Builds a GoogleApiClient. Uses the addApi() method to request the
     * Fitness API.
     */
    protected synchronized void buildGoogleApiClient() {
        mClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(Fitness.HISTORY_API)
                .build();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (mClient == null) {
            buildGoogleApiClient();
        }
        mClient.connect();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        // NOT being called!! WHY??
    }

    @Override
    public void onConnectionSuspended(int cause) {
        mClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // Called called when there was an error connecting the client to the
        // service.
        Log.i(LOG_TAG,
                "onConnectionFailed:" + connectionResult.getErrorCode() + "," + connectionResult.getErrorMessage());
    }
}

1
不是一个好主意,因为它可以被多次调用... 请参阅此处:https://dev59.com/RF0b5IYBdhLWcg3wA9Eb#29712447 - Daniel Nugent
在参考了你的链接之后,我同意你的观点,@DanielNugent。 - Kasim Rangwala

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接