android:使用oauth登录gmail不要求用户ID或密码

时间:2012-10-01 12:06:41

标签: android oauth gmail

在我的应用程序中,我使用oauth登录到我的谷歌帐户,我正在检索所有用户帐户的详细信息。问题是因为我总是登录到我的主要Gmail帐户,我的应用程序将其作为用户帐户。它从不提示用户登录/密码。所以我无法尝试获取任何其他Gmail邮件ID的帐户详细信息。

即使用户已经登录,我怎么强迫要求电子邮件和密码。 我的请求令牌代码在下面给出

public class RequestTokenActivity extends Activity {


ProgressDialog progressDialog;
private OAuthConsumer consumer; 
private OAuthProvider provider;
private SharedPreferences prefs;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i("create","create");

    try {
        consumer = new CommonsHttpOAuthConsumer(C.CONSUMER_KEY, C.CONSUMER_SECRET);
        provider = new CommonsHttpOAuthProvider(
                C.REQUEST_URL  + "?scope=" + URLEncoder.encode(C.SCOPE, C.ENCODING) + "&xoauth_displayname=" + C.APP_NAME,
                C.ACCESS_URL,
                C.AUTHORIZE_URL);
    } catch (Exception e) {
        Log.e(C.TAG, "Error creating consumer / provider",e);
    }

    //getRequestToken();
    new OAuthRequestTokenTask(this,consumer,provider).execute();
}


@Override
public void onNewIntent(Intent intent) {
    Log.i("newin","newintent");
    super.onNewIntent(intent); 
    prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final Uri uri = intent.getData();
    if (uri != null && uri.getScheme().equals(C.OAUTH_CALLBACK_SCHEME)) {
        Log.i(C.TAG, "Callback received : " + uri);
        Log.i(C.TAG, "Retrieving Access Token");
        getAccessToken(uri);
    }
    else {
        new OAuthRequestTokenTask(this,consumer,provider).execute();
    }
}

private void getRequestToken() {
    try {
        Log.d(C.TAG, "getRequestToken() called");
        String url = provider.retrieveRequestToken(consumer, C.OAUTH_CALLBACK_URL);
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
        this.startActivity(intent);

    } catch (Exception e) {
        Log.e(C.TAG, "Error retrieving request token", e);
    }
}

private void getAccessToken(Uri uri) {
    final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
    try {
        provider.retrieveAccessToken(consumer, oauth_verifier);

        final Editor edit = prefs.edit();
        edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken());
        edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret());
        edit.commit();

        String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
        String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");

        consumer.setTokenWithSecret(token, secret);
        this.startActivity(new Intent(this ,OAuthMain.class));

        Log.i(C.TAG, "Access Token Retrieved");

    } catch (Exception e) {
        Log.e(C.TAG, "Access Token Retrieval Error", e);
    }
}
public class OAuthRequestTokenTask extends AsyncTask<Void, Void, Void> {

    final String TAG = getClass().getName();
    private Context context;
    private OAuthProvider provider;
    private OAuthConsumer consumer;

    /**
     * 
     * We pass the OAuth consumer and provider.
     * 
     * @param   context
     *          Required to be able to start the intent to launch the browser.
     * @param   provider
     *          The OAuthProvider object
     * @param   consumer
     *          The OAuthConsumer object
     */
    public OAuthRequestTokenTask(Context context,OAuthConsumer consumer,OAuthProvider provider) {
        this.context = context;
        this.consumer = consumer;
        this.provider = provider;
    }
 @Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    super.onPreExecute();
     progressDialog = new ProgressDialog(RequestTokenActivity.this);
    progressDialog.setCancelable(true);
    progressDialog.setMessage(" Loading ...");
    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressDialog.setProgress(0);
    progressDialog.setOnCancelListener(new OnCancelListener() {

        public void onCancel(DialogInterface arg0) {
            if (progressDialog.isShowing()) 
                progressDialog.dismiss();
            finish();

        }
    });

    progressDialog.show();

}
    /**
     * 
     * Retrieve the OAuth Request Token and present a browser to the user to authorize the token.
     * 
     */
    @Override
    protected Void doInBackground(Void... params) {

        try {
            Log.i(TAG, "Retrieving request token from Google servers");
            final String url = provider.retrieveRequestToken(consumer, C.OAUTH_CALLBACK_URL);
            Log.i(TAG, "Popping a browser with the authorize URL : " + url);
            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
            context.startActivity(intent);

        } catch (Exception e) {
            Log.e(TAG, "Error during OAUth retrieve request token", e);
        }

        return null;
    }
    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        progressDialog.dismiss();
    }

}

}

2 个答案:

答案 0 :(得分:0)

此处的问题不是您的代码,而是您的浏览器设置。

使用

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(
    Intent.FLAG_ACTIVITY_SINGLE_TOP
    | Intent.FLAG_ACTIVITY_NO_HISTORY
    | Intent.FLAG_FROM_BACKGROUND);
context.startActivity(intent);

您正在呼叫外部浏览器以打开Goog​​le的授权页面。如果用户已在该浏览器中登录Google,则系统会要求他批准您的申请。如果他还没有登录,他将首先看到登录屏幕。所以只需注销,即可以其他用户身份登录。

您也可以打开自己的WebView,而不是依赖外部浏览器。如果您没有自己为Web视图实施cookie管理,则用户将始终被要求登录。

答案 1 :(得分:0)

我可能会避免向最终用户询问密码,但是如果您想提示用户使用哪个电子邮件帐户(可能是已经在相关设备上注册的,或者是新的),你可以开始一个帐户选择器意图。

示例伪代码:

//Applicable only to Google accounts for now.
        String[] accountTypes = new String[]{"com.google"};
        Intent intent = AccountPicker.newChooseAccountIntent(null, //There is no currently selected account.
                                                             null, //There is no restricted list of accounts.
                                                             accountTypes, //The dialog should list only accounts from the "com.google" domain.
                                                             true, //prompt the user to pick an account if there's only one available account (just use that one). Even if only one account currently exists, the dialog may include an option for the user to add a new account.
                                                             null, //There is no custom title for the dialog.
                                                             null, //There is no specific auth token type required.
                                                             null, //There are no restrictions based on account features.
                                                             null); //There are no authenticator-specific options.

        //Capture end-users account selection and proceed with SignIn. onActivityResult() will be called once the user has made their selection.
        startActivityForResult(intent, requestCode); //This will initiate a dialog.

一旦startActivityForResult()重新启动,即用户已做出选择,您可以通过以下方式检索所选的电子邮件地址:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case <the request code you passed to startActivityForResult:
                // Receiving a result from the AccountPicker
                if (resultCode == RESULT_OK) {
                    if (data != null) {
                        //Retrieve the chosen email account
                        data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME));
                    } else {
                        //Handle error
                    }
                } else if (resultCode == RESULT_CANCELED) {
                    // The account picker dialog closed without selecting an account.
                    // Notify users that they must pick an account to proceed.
                }
                break;
        }
    } 

请注意,最终用户不受使用AccountManager选择的帐户的限制。毕竟,一旦出现意图对话框,他们总是可以使用“添加帐户”选项。

希望这有帮助。

干杯!