package org.mtransit.android.ui; import java.lang.ref.WeakReference; import org.mtransit.android.commons.MTLog; import org.mtransit.android.commons.TaskUtils; import org.mtransit.android.commons.task.MTAsyncTask; import org.mtransit.android.ui.fragment.MTDialogFragmentV4; import android.app.Activity; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.common.api.GoogleApiClient; public abstract class MTActivityWithGoogleAPIClient extends MTAppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static final int REQUEST_RESOLVE_ERROR = 1001; private static final String DIALOG_ERROR = "dialog_error"; private static final String STATE_RESOLVING_ERROR = "resolving_error"; private boolean resolvingError = false; private boolean useGooglePlayServices = false; private GoogleApiClient googleApiClient; public MTActivityWithGoogleAPIClient(boolean useGooglePlayServices) { this.useGooglePlayServices = useGooglePlayServices; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.resolvingError = savedInstanceState != null && savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false); } public GoogleApiClient getGoogleApiClientOrNull() { return this.googleApiClient; } public GoogleApiClient getGoogleApiClientOrInit() { if (this.useGooglePlayServices && this.googleApiClient == null) { initGoogleApiClient(); } return this.googleApiClient; } private synchronized void initGoogleApiClient() { if (this.googleApiClient != null) { return; } GoogleApiClient.Builder googleApiClientBuilder = new GoogleApiClient.Builder(this); addGoogleAPIs(googleApiClientBuilder); googleApiClientBuilder // .addConnectionCallbacks(this)// .addOnConnectionFailedListener(this); this.googleApiClient = googleApiClientBuilder.build(); } protected abstract void addGoogleAPIs(GoogleApiClient.Builder googleApiClientBuilder); @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_RESOLVING_ERROR, this.resolvingError); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_RESOLVE_ERROR: switch (resultCode) { case Activity.RESULT_OK: GoogleApiClient googleApiClient = getGoogleApiClientOrInit(); if (googleApiClient != null && !googleApiClient.isConnecting() && !googleApiClient.isConnected()) { googleApiClient.connect(); } break; default: MTLog.w(this, "Unexpected artivity result code '%s'.", resultCode); } break; default: MTLog.w(this, "Unexpected artivity request code '%s'.", requestCode); } } @Override protected void onStart() { super.onStart(); if (!this.resolvingError) { TaskUtils.execute(new StartGoogleApiClientTask(this)); } } private static class StartGoogleApiClientTask extends MTAsyncTask<Void, Void, Void> { private static final String TAG = MTActivityWithGoogleAPIClient.class.getSimpleName() + ">" + StartGoogleApiClientTask.class.getSimpleName(); @Override public String getLogTag() { return TAG; } private WeakReference<MTActivityWithGoogleAPIClient> activityWR; public StartGoogleApiClientTask(MTActivityWithGoogleAPIClient activity) { this.activityWR = new WeakReference<MTActivityWithGoogleAPIClient>(activity); } @Override protected Void doInBackgroundMT(Void... params) { MTActivityWithGoogleAPIClient activity = this.activityWR == null ? null : this.activityWR.get(); if (activity == null) { return null; } GoogleApiClient googleApiClient = activity.getGoogleApiClientOrInit(); if (googleApiClient != null) { googleApiClient.connect(); } return null; } } @Override protected void onStop() { super.onStop(); TaskUtils.execute(new StopGoogleApiClientTask(this)); } private static class StopGoogleApiClientTask extends MTAsyncTask<Void, Void, Void> { private static final String TAG = MTActivityWithGoogleAPIClient.class.getSimpleName() + ">" + StopGoogleApiClientTask.class.getSimpleName(); @Override public String getLogTag() { return TAG; } private WeakReference<MTActivityWithGoogleAPIClient> activityWR; public StopGoogleApiClientTask(MTActivityWithGoogleAPIClient activity) { this.activityWR = new WeakReference<MTActivityWithGoogleAPIClient>(activity); } @Override protected Void doInBackgroundMT(Void... params) { MTActivityWithGoogleAPIClient activity = this.activityWR == null ? null : this.activityWR.get(); if (activity == null) { return null; } activity.onBeforeClientDisconnected(); GoogleApiClient googleApiClient = activity.getGoogleApiClientOrNull(); if (googleApiClient != null) { googleApiClient.disconnect(); } return null; } } public abstract void onBeforeClientDisconnected(); @Override protected void onDestroy() { super.onDestroy(); if (this.googleApiClient != null) { this.googleApiClient.unregisterConnectionCallbacks(this); this.googleApiClient.unregisterConnectionFailedListener(this); this.googleApiClient = null; } } @Override public void onConnected(Bundle connectionHint) { onClientConnected(); } public abstract void onClientConnected(); @Override public void onConnectionSuspended(int cause) { } @Override public void onConnectionFailed(ConnectionResult result) { if (this.resolvingError) { return; } if (result.hasResolution()) { try { this.resolvingError = true; result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR); } catch (SendIntentException sie) { MTLog.w(this, sie, "Error while resolving Google Play Services error!"); GoogleApiClient googleApiClient = getGoogleApiClientOrInit(); if (googleApiClient != null) { googleApiClient.connect(); } } } else { showErrorDialog(result.getErrorCode()); this.resolvingError = true; } } private void showErrorDialog(int errorCode) { MainActivity.showNewDialog(getSupportFragmentManager(), ErrorDialogFragment.newInstance(errorCode)); } private void onDialogDismissed() { this.resolvingError = false; } public static class ErrorDialogFragment extends MTDialogFragmentV4 { private static final String TAG = ErrorDialogFragment.class.getSimpleName(); @Override public String getLogTag() { return TAG; } public static ErrorDialogFragment newInstance(int errorCode) { ErrorDialogFragment dialogFragment = new ErrorDialogFragment(); Bundle args = new Bundle(); args.putInt(DIALOG_ERROR, errorCode); dialogFragment.setArguments(args); return dialogFragment; } public ErrorDialogFragment() { } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { int errorCode = getArguments().getInt(DIALOG_ERROR); return GoogleApiAvailability.getInstance().getErrorDialog(getActivity(), errorCode, REQUEST_RESOLVE_ERROR); } @Override public void onDismiss(DialogInterface dialog) { FragmentActivity activity = getActivity(); if (activity != null && activity instanceof MTActivityWithGoogleAPIClient) { ((MTActivityWithGoogleAPIClient) activity).onDialogDismissed(); } } } }