Skip to content Skip to sidebar Skip to footer

How To Pass An Googleapiclient Objet To Another Activity

In my loginactivity, I have an google Sign In button to LogIn. I checked and works fine. I had anothers buttons to log out and Revoke and worked fine too. This is my code of the lo

Solution 1:

This is not a bad idea, in fact it is you should do. If you want to handle all actions and events from Google Auth, the easiest, elegant, reusable, and testeable way to do it is to wrap this logic in one or more clases dedicated to that.

If you have few actions you could encalsupate all of them in only one wrap class. For example you could create a class GoogleSingInWrapper and use the Singleton patter to make sure there is only one instance in your entire app.

publicclassGoogleSingInWrapper {
   privatestatic GoogleSingInWrapper instance;
   private GoogleApiClient mGoogleApiClient;

   privateGoogleSingainWrapper() {
      // Private constructor to deny the creation of this object through the constructor and prevent creating more then one instance
      mGoogleApiClient = /*create your client here*/;
   }

   publicstaticgetInstance(/*params you need*/) {
      if(instance == null)
         instance = new GoogleSingInWrapper (/*params*/);
      return instance;
   }

   publicvoidlogin(/*params*/) {
      // Login
   }

   // Other methods
}

So to get (and create an instance if doesn't exists yet) an instance of GoogleSingInWrapper you use:

GoogleSingInWrapper.gerInstance(/*params*/);

Now if you put all variables and logic in this class you can access them from where you want. The mGoogleApiClient must be in this wrapper.

You can now add all method you need such login, logout and revoke.

And use it as follows:

GoogleSingInWrapper.getInstance().login(/*params*/);
GoogleSingInWrapper.getInstance().logout(/*params*/);
GoogleSingInWrapper.getInstance().revoke(/*params*/);

You shouldn't use mGoogleApiClient directly, it should be encapsulated in GoogleSingInWrapper.

EDIT

When I say mGoogleApiClient should be private inside GoogleSingInWrapper it means that you should't have access to it outside the GoogleSingInWrapper class. If you create a GoogleSingInWrapper but you create a method called

public GoogleApiClient get_GoogleApiClient();

you problems keep existing, because you are still using this mGoogleApiClientin all activities. You don't want this, so you want to be decoupled of this object in all activities.

Following your edits, I'll type here more code, but the more free code I give you less you learn.

publicclassGoogleSingInWrapper {
   privatestaticGoogleSingInWrapper instance;
   privateGoogleApiClient mGoogleApiClient;

   privateGoogleSingainWrapper(Context context) {
      // Private constructor to deny the creation of this object through the constructor and prevent creating more then one instanceGoogleSignInOptions gso = newGoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestEmail() 
        .build(); 

      mGoogleApiClient = newGoogleApiClient.Builder(context)
        .enableAutoManage(this, this)
        .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
        .build(); 
   }

   publicstaticgetInstance(Context context) {
      if(instance == null)
         instance = newGoogleSingInWrapper (/*params*/);
      return instance;
   }

   publicvoidlogin(/*params*/) {
      // Login
   }

   // Other methodspublicvoidlogout(){ 
      if(mGoogleApiClient.isConnected()) {
      Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
            newResultCallback<Status>() {
                @OverridepublicvoidonResult(Status status) {
                    Log.d("LOGOUT-RESULT","LOGOUT");
                } 
            }); 
      }  
   }
}

This should look like your GoogleSingInWrapper. And to call for example logout method, you should call as follows:

if (id == R.id.logout) {
    GoogleSingInWrapper.getInstance(context).logout();
    goLoginScreen(); 
} 

Note the constructor is Private intentionally because you doesn't want to call new GoogleSingInWrapper. If you do that, you are creating multiple instances of this object ant you're breaking the Singleton pattern.

Also, you may note that some processes like login, needs an Activity because the results are posted in onActivityResult. In order to decouple you GoogleSingInWrapper from all your Activities you could create a dedicated Activity to manage all onActivityResults. This activity should be transparent and will be invisible for the user.

You can achieve that with this code:

publicclassGoogleActivityextendsAppCompatActivity {
  publicstaticfinalintRC_SIGN_IN=1000;

  privatestaticfinalStringACTION="calling_action";

  publicstatic Intent getIntent(Context context, int action, Intent actionIntent) {
    Intenti=newIntent(context, GoogleActivity.class);
    i.putExtra(ACTION, action);
    i.putExtra(Intent.EXTRA_INTENT, actionIntent);
    return i;
  }

  @OverrideprotectedvoidonCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

    Intent actionIntent;
    intaction= getIntent().getIntExtra(ACTION, 0);
    switch (action) {
      case RC_SIGN_IN:
        actionIntent = (Intent) getIntent().getExtras().get(Intent.EXTRA_INTENT);
        if (actionIntent != null)
          startActivityForResult(actionIntent, RC_SIGN_IN);
        break;
      case0:
      default:
        break;
    }
  }

  @OverrideprotectedvoidonActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
      case RC_SIGN_IN:
        GoogleSignInResultresult= Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        handleSignInResult(result);
        finish();
        return;
    }
  }
}

Then set the transparent theme in the manifest for this Activity:

<activityandroid:name=".data.drive.GoogleActivity"android:theme="@style/TransparentActivity"/>

And define your transparent style in your values folder:

<stylename="TransparentActivity"parent="Theme.AppCompat.Light.NoActionBar"><itemname="android:windowIsTranslucent">true</item><itemname="android:windowBackground">@android:color/transparent</item><itemname="android:windowContentOverlay">@null</item><itemname="android:windowNoTitle">true</item><itemname="android:windowIsFloating">true</item><itemname="android:backgroundDimEnabled">false</item></style>

Now you have to catch all pieces I've done and construct your final product in order to get it working.

Post a Comment for "How To Pass An Googleapiclient Objet To Another Activity"