GoogleApiClient onConnected 未被調用,在服務中使用 (GoogleApiClient onConnected not being called, using in a Service)


問題描述

GoogleApiClient onConnected 未被調用,在服務中使用 (GoogleApiClient onConnected not being called, using in a Service)

當我在 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 在 Service 中工作?

服務是從 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");
    }
};

}

在調試過程中,我可以看到服務的 onCreate 被調用,但是 onConnected 從未被調用。就我所見,日誌中沒有什麼特別之處。


參考解法

方法 1:

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

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

方法 3:

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

方法 4:

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.

(by rukimanAshana.JackolDhaval PatelKasim RangwalaNaofumi)

參考文件

  1. GoogleApiClient onConnected not being called, using in a Service (CC BY‑SA 2.5/3.0/4.0)

#android-googleapiclient #Android






相關問題

Scope 在 GoogleApiClient 中的作用是什麼? (What does Scope do in GoogleApiClient?)

Android studio - 將 GCM api 更新為 Google 服務 (Android studio - updating GCM api to Google services)

Android:為沒有 Google Play 服務的用戶登錄 Google? (Android: Google signin for a user without Google Play Services?)

GoogleApiClient onConnected 未被調用,在服務中使用 (GoogleApiClient onConnected not being called, using in a Service)

從 Play 商店安裝應用程序後嘗試使用 Google 登錄時出現“使用 Google 進行身份驗證時出錯:未知”異常。閱讀詳情 (Getting 'Error authenticating with Google: unknown' exception when trying to signin with google after installing app from play store. See details)

Android google Sign In 總是顯示 handleSignInResult:false (Android google Sign In always shows handleSignInResult:false)

Android Google Play 遊戲服務 (Android Google Play Games Services)

android - 即使沒有可用的互聯網,也會調用 onLocationChanged (android - onLocationChanged is called even when there is not internet available)







留言討論