0

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 loggin screen.

 import android.app.ProgressDialog;
 import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.google.android.gms.auth.api.Auth;
  import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
   import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.OptionalPendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;

import java.util.ArrayList;
 import java.util.List;

 public class MainActivity extends AppCompatActivity implements
    View.OnClickListener,
    GoogleApiClient.OnConnectionFailedListener
{

private static final String TAG = MainActivity.class.getSimpleName();
private static final int RC_SIGN_IN = 007;

private GoogleApiClient mGoogleApiClient;
private ProgressDialog mProgressDialog;

private SignInButton btnSignIn;

List<String> profile=new ArrayList<>();
private MyGoogleApi_Singleton myGoogleApi_singleton;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnSignIn = (SignInButton) findViewById(R.id.sign_in_button);
    btnSignIn.setOnClickListener(this);

    updateUI(false);

    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, this)
            .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
            .build();

    /* Customizing G+ button
    btnSignIn.setSize(SignInButton.SIZE_STANDARD);
    btnSignIn.setScopes(gso.getScopeArray());*/

    //Create a new objet to handle in all class
    myGoogleApi_singleton= new MyGoogleApi_Singleton();
    myGoogleApi_singleton.getInstance(mGoogleApiClient);
}


private void signIn()
{
    Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
    startActivityForResult(signInIntent, RC_SIGN_IN);

}


private void signOut()
{
    Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
            new ResultCallback<Status>()
            {
                @Override
                public void onResult(Status status)
                {
                    updateUI(false);
                }
            });
}

private void revokeAccess()
{
    Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
            new ResultCallback<Status>()
            {
                @Override
                public void onResult(Status status)
                {
                    updateUI(false);
                }
            });
}

private void handleSignInResult(GoogleSignInResult result)
{
    Log.d(TAG, "handleSignInResult:" + result.isSuccess());
    if (result.isSuccess())
    {
        // Signed in successfully, show authenticated UI.
        GoogleSignInAccount acct = result.getSignInAccount();

        String personName = acct.getDisplayName();
        String personPhotoUrl = acct.getPhotoUrl().toString();
        String email = acct.getEmail();
        String idnumber= acct.getId();

        Log.e(TAG, "Name: " + personName + ", email: " + email
                + ", Image: " + personPhotoUrl+ ", Id Number: "+ idnumber);
        //Save the data into the arraylist
        profile.add(idnumber);
        profile.add(personName);
        profile.add(email);
        profile.add(personPhotoUrl);

        //save into sharedpreferences
        StringBuilder stringBuilder = new StringBuilder();

        for (String s:profile)
        {
            stringBuilder.append(s);
            stringBuilder.append(",");
        }

        SharedPreferences sharpref = getSharedPreferences("ProfileList",0);
        SharedPreferences.Editor editor = sharpref.edit();
        editor.putString("ProfileList", stringBuilder.toString());
        editor.commit();

        goIndexScreen();
    } else
        {
        // Signed out, show unauthenticated UI.
        updateUI(false);
        }
}

@Override
public void onClick(View v)
{
    switch (v.getId())
    {
        case R.id.sign_in_button:
            signIn();
            break;

        default:
            break;
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
    if (requestCode == RC_SIGN_IN)
    {
        GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        handleSignInResult(result);
    }
}

@Override
public void onStart()
{
    super.onStart();

    OptionalPendingResult<GoogleSignInResult> opr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
    if (opr.isDone())
    {
        // If the user's cached credentials are valid, the OptionalPendingResult will be "done"
        // and the GoogleSignInResult will be available instantly.
        Log.d(TAG, "Got cached sign-in");
        GoogleSignInResult result = opr.get();
        handleSignInResult(result);
    } else
        {
        // If the user has not previously signed in on this device or the sign-in has expired,
        // this asynchronous branch will attempt to sign in the user silently.  Cross-device
        // single sign-on will occur in this branch.
        showProgressDialog();
        opr.setResultCallback(new ResultCallback<GoogleSignInResult>()
        {
            @Override
            public void onResult(GoogleSignInResult googleSignInResult)
            {
                hideProgressDialog();
                handleSignInResult(googleSignInResult);
            }
        });
    }
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult)
{
    // An unresolvable error has occurred and Google APIs (including Sign-In) will not
    // be available.
    Log.d(TAG, "onConnectionFailed:" + connectionResult);
}

//method to show a progress dialog during the SignIn
private void showProgressDialog()
{
    if (mProgressDialog == null)
    {
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.setIndeterminate(true);
    }

    mProgressDialog.show();
}

//method to hide the progress dialog
private void hideProgressDialog()
{
    if (mProgressDialog != null && mProgressDialog.isShowing())
    {
        mProgressDialog.hide();
    }
}
//method to show or hide the buttons
private void updateUI(boolean isSignedIn)
{
    if (isSignedIn)
    {
        btnSignIn.setVisibility(View.GONE);


    } else
        {
        btnSignIn.setVisibility(View.VISIBLE);

        }
}
//method to go to next activity
private void goIndexScreen()
{
    Intent intent=new Intent(this,Index.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

}

When the login is succes, the app jump to another activity. I need to LogOut from this activity, but I need to a mGoogleApiClient from LoginActivity and I don´t know how I could doing.

I have create a new class (singleton) here my code

import com.google.android.gms.common.api.GoogleApiClient;

class MyGoogleApi_Singleton {
private static final String TAG = "GoogleApiClient";

private static MyGoogleApi_Singleton instance = null;

private static GoogleApiClient mGoogleApiClient = null;

private MyGoogleApi_Singleton(Context context) {
    GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestEmail()
            .build();

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

}

public static MyGoogleApi_Singleton getInstance(Context context) {

    if(instance == null) {
        instance = new MyGoogleApi_Singleton(context);

    }

    return instance;
}


//methods SingIn,SignOut and Revoke
public void Login(GoogleApiClient bGoogleApiClient){


}

public void Logout(){
    if(mGoogleApiClient.isConnected()) {
        Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
                new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                        Log.d("LOGOUT-RESULT","LOGOUT");
                    }
                });
    }

}

public void Revoke() {
    if ((mGoogleApiClient.isConnected())) {
        Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
                new ResultCallback<Status>() {
                    @Override
                    public void onResult(Status status) {
                    Log.d("REVOKE-RESULT","REVOKE");
                    }
                });
    }
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}
}

This is the code of Index activity

   import android.content.Intent;
   import android.content.SharedPreferences;
   import android.os.Bundle;
   import android.support.annotation.NonNull;
    import android.support.design.widget.FloatingActionButton;
   import android.support.design.widget.Snackbar;
   import android.util.Log;
   import android.view.View;
   import android.support.design.widget.NavigationView;
   import android.support.v4.view.GravityCompat;
   import android.support.v4.widget.DrawerLayout;
   import android.support.v7.app.ActionBarDrawerToggle;
   import android.support.v7.app.AppCompatActivity;
   import android.support.v7.widget.Toolbar;
   import android.view.Menu;
   import android.view.MenuItem;
   import android.widget.ImageView;
   import android.widget.TextView;

   import com.bumptech.glide.Glide;
   import com.google.android.gms.auth.api.Auth;
   import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
   import com.google.android.gms.common.ConnectionResult;
   import com.google.android.gms.common.api.GoogleApiClient;
   import com.google.android.gms.common.api.ResultCallback;
   import com.google.android.gms.common.api.Status;
   import com.google.android.gms.tasks.OnCompleteListener;
   import com.google.android.gms.tasks.Task;

   import java.util.ArrayList;
   import java.util.List;

 public class Index extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {
private ImageView ivprofile;
private TextView tvname;
private TextView tvemail;
private TextView tvidnumber;
private String picprofile;
private String name;
private String idnumber;
private String email;
final List<String> profile = new ArrayList<String>();
private View headerview;

private GoogleApiClient mGoogleApiClient;
private MyGoogleApi_Singleton myGoogleApiSingleton;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_index);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    //create a headerview to conect to header of left menu
    headerview=navigationView.getHeaderView(0);

    ivprofile=(ImageView)headerview.findViewById(R.id.imageProfile);
    tvname=(TextView)headerview.findViewById(R.id.fullName);
    tvemail=(TextView)headerview.findViewById(R.id.email);
    tvidnumber=(TextView) headerview.findViewById(R.id.idNumber);

    //Load file saved by sharedpreferences into a new arraylist
    final SharedPreferences sharpref = getSharedPreferences("ProfileList",0);
    String Items = sharpref.getString("ProfileList","");
    String [] listItems = Items.split(",");
    for (int i=0;i<listItems.length;i++){
        profile.add(listItems[i]);
    }

    //get the profile

    idnumber=profile.get(0);
    name=profile.get(1);
    email=profile.get(2);
    picprofile=profile.get(3);

    Log.d("ArrayPerfil", name+email+idnumber+picprofile);

    tvname.setText(name);
    tvidnumber.setText(idnumber);
    tvemail.setText(email);
    Glide.with(this).load(picprofile).into(ivprofile);

    //get the mgoogleapiclient objet
    myGoogleApiSingleton=new MyGoogleApi_Singleton();
    mGoogleApiClient=myGoogleApiSingleton.get_GoogleApiClient();


@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.index, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_camera) {
        // Handle the camera action
    } else if (id == R.id.nav_gallery) {

    } else if (id == R.id.nav_slideshow) {

    } else if (id == R.id.nav_manage) {

    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }else if (id == R.id.logout) {
        myGoogleApiSingleton.getInstance(context).Logout();
        goLoginScreen();
    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}
//method to go to login screen
private void goLoginScreen() {
    Intent intent=new Intent(this,MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

}

As you told me, I created a Transparent Activity. I added the method handleSignInResult because is calling on the method OnActivityResult.

This is the code:

public class GoogleActivity extends AppCompatActivity {
public static final int RC_SIGN_IN = 1000;

private static final String ACTION = "calling_action";

public static Intent getIntent(Context context, int action, Intent actionIntent) {
    Intent i = new Intent(context, GoogleActivity.class);
    i.putExtra(ACTION, action);
    i.putExtra(Intent.EXTRA_INTENT, actionIntent);
    return i;
}

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

    Intent actionIntent;
    int action = 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;
        case 0:
        default:
            break;
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case RC_SIGN_IN:
            GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
            handleSignInResult(result);
            finish();
            return;
    }
}
private void handleSignInResult(GoogleSignInResult result)
{

    if (result.isSuccess())
    {
        // Signed in successfully
        Log.d("SIGNIN", "YOU ARE LOG IN");


    } else
    {
        // Signed out,
        Log.d("SIGNIN", "YOU ARE NOT LOG IN");
    }
}

}

I wait for your help!

Thanks!

  • Did my answer helped you? – Marc Estrada Jun 08 '18 at 22:10
  • Not yet.I edited the question.I add all my code because I think I have a problem handling my google tokken... – Pedro Cañibano Zuñiga Jun 11 '18 at 18:08
  • You have to set `mGoogleApiClient` as a private variable inside your `MyGoogleApi_Singleton` and then add the methods `login`, `logout` and `revoke` to isolate the logic. Using a `MyGoogleApi_Singleton` having to pass as a parameter `mGoogleApiClient` is the same problem you had at start. Try to follow better my answer. The parameters I wrote don't are `mGoogleApiClient` but other params you could need to create the instance of `mGoogleApiClient` – Marc Estrada Jun 13 '18 at 06:26
  • Thankyou again for your response! I edited my Singleton Class. The objet mGoogleApiClient was private, I didn`t need change it. I added three methods. Login,Logout and Revoke. But when I call this methods from my Index class, doing nothing. You will think I'am stupid...but I try to follow your instructions,but I'am learning and I can't solve it...I hope that you can explain the solution .Millones de gracias por adelantado! ;) – Pedro Cañibano Zuñiga Jun 18 '18 at 17:51
  • Let me help you when I have some time. There are some wrong things we should fix in order to get this working :) And maybe we could continue the discussion in a chat room (maybe speaking spanish? :p) – Marc Estrada Jun 19 '18 at 06:06
  • Ok ok, no problem. I'm New here, you contact to me by chat room, in spanish of course, My english is shit! Jajajaja Thankyou again! – Pedro Cañibano Zuñiga Jun 19 '18 at 10:33
  • woops, you can't talk in chat because you don't have enough reputation, its needed at least 20. Let me study your code and I'll help you. – Marc Estrada Jun 19 '18 at 12:37
  • I've update my answer providing a lot of more useful code, but I'm figuring out that this question is too broad to be resolved here. Please let me know if my edit helps you, and good luck :) I can't help you more right now :( – Marc Estrada Jun 19 '18 at 13:52
  • Thankyou for your help! I will try again! :) Now I understand what you told me,except the New transparent activity. I will read again a few times and looking for some information about this. When I will change My code and check it, I will coment. Thankyou again! – Pedro Cañibano Zuñiga Jun 19 '18 at 20:13
  • The transpareu activity is used to manage the requests for `startActivityResult()` and `onActivityResult` callback outside your UI `Activities` and decouple the Google SingIn logic outside the activities. Instead of call the singIn `Intent` from your `Activity` you call it in your new transparent `Acticity` from `GoogleSingainWrapper` in login method. – Marc Estrada Jun 19 '18 at 21:11
  • Hello again! I edited my code. I delete the objet of MyGoogleApi_singleton from "OnCreate of ActivityMain". I just added on MyGoogleApi_Singleton class "onConnectionFailed" method because is necesary. In the transparent activity, as you see, Its needed to implement the method "handleSignInResult" because is calling "onActivityResult". Ok, the problem is on the singleton pattern, when I create an mGoogleApiClient I have an error, and then, I have another error when I check the instance. I think the problem is in "context" I don`t understand this... Lo siento, se que soy un pesado :_( – Pedro Cañibano Zuñiga Jun 20 '18 at 17:55
  • Hello! Finally, I found the solution without needed singleton pattern and transparent activity. I will edit my code for help everybody. Thankyou for your amazing help! Now I know the use of singleton! Thankyou very much!! – Pedro Cañibano Zuñiga Jun 21 '18 at 19:35
  • Sorry, didn't see your last comment. I'm glad to hear that! Your question was really broad and there are a lot of possible solutions to it. At least you learned something :) you're welcome! – Marc Estrada Jun 21 '18 at 19:43

1 Answers1

2

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.

public class GoogleSingInWrapper {
   private static GoogleSingInWrapper instance;
   private GoogleApiClient mGoogleApiClient;

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

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

   public void login(/*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.

public class GoogleSingInWrapper {
   private static GoogleSingInWrapper instance;
   private GoogleApiClient mGoogleApiClient;

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

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

   public static getInstance(Context context) {
      if(instance == null)
         instance = new GoogleSingInWrapper (/*params*/);
      return instance;
   }

   public void login(/*params*/) {
      // Login
   }

   // Other methods
   public void logout(){ 
      if(mGoogleApiClient.isConnected()) {
      Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
            new ResultCallback<Status>() {
                @Override 
                public void onResult(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:

public class GoogleActivity extends AppCompatActivity {
  public static final int RC_SIGN_IN = 1000;

  private static final String ACTION = "calling_action";

  public static Intent getIntent(Context context, int action, Intent actionIntent) {
    Intent i = new Intent(context, GoogleActivity.class);
    i.putExtra(ACTION, action);
    i.putExtra(Intent.EXTRA_INTENT, actionIntent);
    return i;
  }

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

    Intent actionIntent;
    int action = 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;
      case 0:
      default:
        break;
    }
  }

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

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

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

And define your transparent style in your values folder:

<style name="TransparentActivity" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
    <item name="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.

Marc Estrada
  • 1,657
  • 10
  • 20