【问题标题】:GoogleApiClient onConnected not being called, using in a ServiceGoogleApiClient onConnected 未被调用,在服务中使用
【发布时间】:2016-03-30 03:32:06
【问题描述】:

当我在 Activity 中使用 GoogleApiClient 但将其移至服务并且未调用 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 调用的

公共类 MainActivity 扩展 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");
    }
};

}

在调试过程中,我可以看到服务的 onCreate 被调用,但是 onConnected 从未被调用。就我所见,日志中没有什么特别之处。

【问题讨论】:

  • 你能说明你是如何启动服务的吗?还要检查日志中的任何错误。

标签: android android-googleapiclient


【解决方案1】:

首先实现这些接口:

  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();
}

【讨论】:

  • 赞成。忘记添加 googleApiclient.connect();这就是原因,这么小的原因。
【解决方案2】:

addOnConnectionFailedListener 添加到GoogleApiClient 以跟踪错误。根据 doc 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());
    }
}

【讨论】:

  • 我得到 onConnectionFailed:4,null
  • 啊,我想这是因为我在另一台计算机上工作,因此开发人员证书与我用来激活 Google Fitness API 的证书不同。我会试试的。
  • 根据doc,错误代码4表示,客户端尝试连接服务但用户未登录。
  • 如何修复该错误?我已经使用 debug.keystore 的 SHA1 创建了 OAuth 客户端 ID。但我仍然得到同样的错误。
  • 你需要从activity连接一次Fitness api。以便用户使用所需的 Google 帐户登录。
【解决方案3】:

试试这个。

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());
    }
}

【讨论】:

  • 不是一个好主意,因为它可以被多次调用...见这里:stackoverflow.com/a/29712447
  • @DanielNugent 在引用您的链接后。我同意你的看法。
【解决方案4】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多