GoogleApiClient onConnected not being called, using in a Service
Asked Answered
D

4

8

Was working when I was using GoogleApiClient in an Activity but moved it to a Service and the onConnected is not being called.

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) {
}

}

Any ideas anyone? What am I doing wrong? Has anyone got GoogleApiClient working in a Service?

The service is called from an 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");
    }
};

}

During debugging I can see the onCreate of the Service gets called, however the onConnected is never called. Nothing special in the logs from what I can see.

Dallman answered 30/3, 2016 at 3:32 Comment(1)
Can you show how you start the service? Also check for any errors in the logs.Swartz
C
10

First implement these interfaces:

  1. GoogleApiClient.ConnectionCallbacks
  2. GoogleApiClient.OnConnectionFailedListener

Then you will have to add these methods to your class:

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

As soon as you connect, the OnConnected method will be called. In this method can you do whatever you want, like getting the current location, the location address, add a marker point to map, etc.

But you cannot do anything without establishing a connection to the Google API client. To connect to the GoogleAPIClient, you can add this method to your class and call it in your onCreate method.

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();
}
Coming answered 24/5, 2017 at 7:34 Comment(1)
Upvoted. Forgot to add googleApiclient.connect(); this was the cause, such a little cause.Derisive
B
2

Add addOnConnectionFailedListener to GoogleApiClient to track the error. As per doc addOnConnectionFailedListener called when there was an error connecting the client to the service.

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());
    }
}
Barrera answered 30/3, 2016 at 4:16 Comment(9)
I get onConnectionFailed:4,nullDallman
Ah I think its because I'm working at a different computer and so the developer certificate is different to what I used to activate the Google fitness API. I'll try that.Dallman
As per doc, Error code 4 means, The client attempted to connect to the service but the user is not signed in.Barrera
How do I fix that error? I have already created a OAuth Client ID using the SHA1 of my debug.keystore. But I still get the same error.Dallman
You need to connect to Fitness api from activity once. so that user will signin with desired google account.Barrera
Tried that but no luck :(Dallman
@Dallman replace onConnectionFailed method with pastebin.com/0Z9sCiQp content and try again. Also add onActivityResult method. And try this in activity not in service .Barrera
OK I got it to work in an activity using GoogleApiClient.enableAutoManage() seems like this handles the dialog to select an account from. Now it is working. Thanks for your help.Dallman
So the answer was to connect in an activity first, this way the service is able to connect.Dallman
F
0

try this.

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());
    }
}
Fail answered 30/3, 2016 at 4:35 Comment(2)
Not a good idea, as it can be called multiple times... See here: stackoverflow.com/a/29712447Swartz
@DanielNugent after referring your link. I'm agree with you.Fail
N
0

I had a same issue when I was using useDefaultAccount() to create a client. I then replaced it with setAccountName() and it starts working. I think for some reasons accountpicker doesn't work in service that's why googleapiclient's connect() silently failed since you need specify which account you use for retrieving Fitness info. Noted that you need to have an account picker in your activity and pass the email account to your service in some way.

Neoma answered 1/9, 2016 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.