Google+ を使用してアプリケーションにサインインすると奇妙な問題が発生します。次の順序で Google+ を使用すると、次の 3 つのダイアログが表示されます。
それから:
最後に、前の 2 つの画面を組み合わせた画面:
最終的には機能しますが、ユーザーがこのオプションを使用するのは非常にイライラするでしょう。この問題が発生した理由や修正方法を知っている人はいますか?
これが私のコードです:
ログイン アクティビティ:
@Override
public void onClick(View view) {
if (view.getId() == R.id.google_login_button)
{
auth = Login.instance.getAuthenticationType();
Login.instance.setUpAuthentication(this, Google.class.getName(), new ConnectCallback() {
@Override
public void onConnected(String token) {
finishActivity();
}
@Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
});
}
}
ログインオブジェクト:
public class Login {
private static final String TAG = Login.class.getSimpleName();
public static Login instance = new Login();
public static int startLoginCounter = 0;
private Authentication auth;
public FragmentActivity context;
private ConnectCallback callback = new ConnectCallback() {
@Override
public void onConnected(String token) {
CupsLog.i(TAG, "Logged in with token: " + token);
if (auth.getAuthType().equalsIgnoreCase(Google.class.getName())) {
CupsTracker.instance.sendAnalyticsEvent(CupsTracker.LOGIN, CupsTracker.GOOGLE_LOGIN, CupsTracker.GOOGLE_LOGIN, null);
CupsTracker.instance.trackMobileAppTrackerAction(CupsTracker.GOOGLE_LOGIN);
}
if (auth.getAuthType().equalsIgnoreCase(Facebook.class.getName())) {
CupsTracker.instance.sendAnalyticsEvent(CupsTracker.LOGIN, CupsTracker.FACEBOOK_LOGIN, CupsTracker.FACEBOOK_LOGIN, null);
CupsTracker.instance.sendAnalyticsView("fb login");
CupsTracker.instance.trackMobileAppTrackerAction(CupsTracker.FACEBOOK_LOGIN);
}
AccountService.instance.pullAccountDetailsFromServer();
WebFragment webFragment = (WebFragment) context.getSupportFragmentManager().findFragmentById(R.id.venue_fragment);
webFragment.loadUrlInvisible(Consts.venueUri("C001"));
}
@Override
public void onDisconnected() {
CupsLog.i(TAG, "Logged out");
CookieUtil.instance.removeAllCookies();
FileAccessUtil.instance.removeParameter(Consts.AUTH_TYPE);
auth = null;
startLoginCounter++;
CupsLog.i(TAG, "startLoginCounter: " + startLoginCounter);
if (startLoginCounter < 2)
{
Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
}
};
public void login(FragmentActivity context) {
this.context = context;
auth = getAuthenticationType();
if (auth == null) {
Session.Builder builder = new Session.Builder(context);
Session session = builder.build();
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) { // if the user had a facebook session then keep him logged in with facebook for backwards compatibility
if (!FileAccessUtil.instance.isEqualString(Consts.AUTH_TYPE, Facebook.class.getName())) {
FileAccessUtil.instance.setStringProperty(Consts.AUTH_TYPE, Facebook.class.getName());
}
auth = getAuthenticationType();
Facebook.instance.login(context, callback);
} else {
// call login activity if this is a new user
Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
} else {
auth.login(context, callback);
}
}
public void logout(Activity context) {
if (auth != null) {
AccountService.instance.setAccount(null);
auth.logout(context, callback);
}
}
public void setUpAuthentication(Activity loginActivity, String type, ConnectCallback callback) {
if (type.equals(Google.class.getName())) {
auth = Google.instance;
} else if (type.equalsIgnoreCase(Facebook.class.getName())) {
auth = Facebook.instance;
}
auth.onCreate(context);
auth.setLoginActivity(loginActivity);
auth.login(context, callback);
}
public Authentication getAuthenticationType() {
String type = FileAccessUtil.instance.getStringProperty(Consts.AUTH_TYPE);
if (type != null) {
if (type.equalsIgnoreCase(Google.class.getName()))
return Google.instance;
else if (type.equalsIgnoreCase(Facebook.class.getName()))
return Facebook.instance;
else
return null;
}
return null;
}
public interface ConnectCallback {
public void onConnected(String token);
public void onDisconnected();
}
}
Googleオブジェクト:
public class Google implements ConnectionCallbacks, Authentication, OnConnectionFailedListener {
private static final String TAG = Google.class.getSimpleName();
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
private static final int REQUSET_TOKEN_PERMISSIONS_RESLOVE_ERR = 9001;
public static final Google instance = new Google();
private PlusClient mPlusClient;
private Activity loginActivity;
private String authToken;
private ConnectCallback connectCallback;
private String visiblaeActivities = "http://schemas.google.com/AddActivity";
// A flag to stop multiple dialogues appearing for the user.
private boolean mResolveOnFail;
@Override
public void onCreate(Activity context) {
mPlusClient = new PlusClient.Builder(context, this, this).setActions(visiblaeActivities).build();
mResolveOnFail = false;
}
@Override
public void onConnected(Bundle result) {
mResolveOnFail = false;
fetchAuthToken();
}
@Override
public void onDisconnected() {
authToken = null;
if (connectCallback != null) {
connectCallback.onDisconnected();
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
//The user clicked the sign-in button already. Start to resolve
// connection errors. Wait until onConnected() to dismiss the
// connection dialog.
if (result.hasResolution()) {
if (mResolveOnFail) {
try {
if (loginActivity != null) {
mResolveOnFail = false;
result.startResolutionForResult(loginActivity, REQUEST_CODE_RESOLVE_ERR);
} else {
Intent intent = new Intent(Login.instance.context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Login.instance.context.startActivity(intent);
}
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
}
}
public PlusClient getPlusClient() {
return this.mPlusClient;
}
@Override
public void onActivityResult(int requestCode, int responseCode, Intent data) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == Activity.RESULT_OK) {
mResolveOnFail = true;
//mConnectionResult = null;
mPlusClient.connect();
}
if (requestCode == REQUSET_TOKEN_PERMISSIONS_RESLOVE_ERR && responseCode == Activity.RESULT_OK) {
if (isConnected())
fetchAuthToken();
}
}
@Override
public boolean isConnected() {
if (getPlusClient() != null) {
return getPlusClient().isConnected();
} else return false;
}
@Override
public String getAuthToken() {
return authToken;
}
private void setTokenCookie() {
String val = "google+" + getAuthToken();
CupsLog.i(TAG, "Google access_token: " + val);
CookieUtil.instance.setCookie("auth", val, true);
}
@Override
public String getAuthType() {
return Google.class.getName();
}
@Override
public void login(Activity context, ConnectCallback callback) {
this.connectCallback = callback;
if (mPlusClient == null) {
onCreate(context);
}
mResolveOnFail = true;
mPlusClient.connect();
}
@Override
public void logout(Activity context, final ConnectCallback callback) {
if (getPlusClient() != null && mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
GoogleAuthUtil.invalidateToken(context, getAuthToken());
mPlusClient.revokeAccessAndDisconnect(new OnAccessRevokedListener() {
@Override
public void onAccessRevoked(ConnectionResult arg0) {
callback.onDisconnected();
}
});
}
}
private void fetchAuthToken() {
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String token = null;
String scope = "oauth2: https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email";//"oauth2: "+ Scopes.PLUS_PROFILE;
Bundle appActivities = new Bundle();
appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES, visiblaeActivities);
try {
// We can retrieve the token to check via tokeninfo or to pass to a service-side application.
int isGooglePlayServiceAvilable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(Login.instance.context);
if (isGooglePlayServiceAvilable == ConnectionResult.SUCCESS)
{
token = GoogleAuthUtil.getToken(Login.instance.context, mPlusClient.getAccountName(), scope, appActivities);
}
else
{
GooglePlayServicesUtil.getErrorDialog(isGooglePlayServiceAvilable, loginActivity, 12).show();
}
} catch (UserRecoverableAuthException e) {
// This error is recoverable, so we could fix this
// by displaying the intent to the user.
Intent intent = e != null ? e.getIntent() : null; //fixes two crashlytics bugs
if (intent != null) {
if (loginActivity != null) loginActivity.startActivityForResult(intent, REQUSET_TOKEN_PERMISSIONS_RESLOVE_ERR);
else Login.instance.context.startActivityForResult(intent, REQUSET_TOKEN_PERMISSIONS_RESLOVE_ERR);
}
} catch (IOException e) {
e.printStackTrace();
} catch (GoogleAuthException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return token;
}
@Override
protected void onPostExecute(String result) {
authToken = result;
setTokenCookie();
if (authToken != null) {
if (connectCallback != null) {
connectCallback.onConnected(authToken);
}
}
}
};
task.execute((Void) null);
}
}