How To Pass An Googleapiclient Objet To Another Activity
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 mGoogleApiClient
in 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"