GoogleApiClient onConnected не вызывается, используется в службе

Работал, когда я использовал 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 никогда не вызывается. В логах ничего особенного из того, что я вижу.


person rukiman    schedule 30.03.2016    source источник
comment
Можете ли вы показать, как вы запускаете службу? Также проверьте наличие ошибок в журналах.   -  person Daniel Nugent    schedule 30.03.2016


Ответы (4)


Сначала реализуйте эти интерфейсы:

  1. GoogleApiClient.ConnectionCallbacks
  2. GoogleApiClient.OnConnectionFailedListener

Затем вам нужно будет добавить эти методы в свой класс:

  1. public void onConnected (последний пакет Bundle)
  2. public void onConnectionSuspended (final int i)
  3. public void onConnectionFailed (окончательный результат соединения 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();
}
person Ashana.Jackol    schedule 24.05.2017
comment
Проголосовал. Забыл добавить googleApiclient.connect(); это была причина, такая маленькая причина. - person CodeToLife; 17.11.2017

Добавьте 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());
    }
}
person Dhaval Patel    schedule 30.03.2016
comment
Я получаю onConnectionFailed:4, null - person rukiman; 30.03.2016
comment
Ах, я думаю, это потому, что я работаю на другом компьютере, поэтому сертификат разработчика отличается от того, что я использовал для активации фитнес-API Google. Я попробую это. - person rukiman; 30.03.2016
comment
Согласно документу, Код ошибки 4 означает, что клиент попытался подключиться к службе, но пользователь не выполнил вход. - person Dhaval Patel; 30.03.2016
comment
Как исправить эту ошибку? Я уже создал идентификатор клиента OAuth, используя SHA1 моего debug.keystore. Но я все еще получаю ту же ошибку. - person rukiman; 30.03.2016
comment
Вам нужно подключиться к Fitness API из активности один раз. так что пользователь войдет в желаемую учетную запись Google. - person Dhaval Patel; 30.03.2016
comment
Пробовал, но не повезло :( - person rukiman; 31.03.2016
comment
@rukiman замените метод onConnectionFailed содержимым pastebin.com/0Z9sCiQp и повторите попытку. Также добавьте метод onActivityResult. И попробуйте это в действии, а не в служении. - person Dhaval Patel; 31.03.2016
comment
ОК, я заставил его работать в действии, используя GoogleApiClient.enableAutoManage(), похоже, что это обрабатывает диалоговое окно для выбора учетной записи. Теперь это работает. Спасибо за вашу помощь. - person rukiman; 31.03.2016
comment
Таким образом, ответ заключался в том, чтобы сначала подключиться к действию, чтобы служба могла подключиться. - person rukiman; 31.03.2016

попробуй это.

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());
    }
}
person Kasim Rangwala    schedule 30.03.2016
comment
Не очень хорошая идея, так как ее можно вызывать несколько раз... См. здесь: stackoverflow.com/a/29712447 - person Daniel Nugent; 30.03.2016
comment
@DanielNugent после ссылки на вашу ссылку. Я согласен с вами. - person Kasim Rangwala; 30.03.2016

У меня была такая же проблема, когда я использовал useDefaultAccount() для создания клиента. Затем я заменил его на setAccountName(), и он начал работать. Я думаю, что по каким-то причинам средство выбора аккаунта не работает в сервисе, поэтому googleapiclient connect() не работает, так как вам нужно указать, какую учетную запись вы используете для получения информации о фитнесе. Отмечено, что вам нужно иметь средство выбора учетной записи в своей деятельности и каким-то образом передать учетную запись электронной почты в свою службу.

person Naofumi    schedule 01.09.2016