0

私のアプリでは、oauthを使用してGoogleアカウントにログインし、すべてのユーザーアカウントの詳細を取得しています。問題は、私は常にメインのGmailアカウントにログオンしているため、アプリがそれをユーザーアカウントとして使用していることです。ユーザーのログイン/パスワードの入力を求められることはありません。そのため、他のGmailIDのアカウントの詳細を取得することはできません。

ユーザーがすでにログインしている場合でも、強制的に電子メールとパスワードを要求するにはどうすればよいですか。私の要求トークンコードを以下に示します。

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();
    }

}

}

4

2 に答える 2

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 を使用してどのアカウントを選択するかについて制限されないことに注意してください。結局のところ、インテント ダイアログが表示されたら、いつでも [アカウントの追加] オプションを使用できます。

お役に立てれば。

乾杯!

于 2014-12-25T06:20:49.260 に答える
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);

Google の認証ページを開くために外部ブラウザを呼び出しています。ユーザーがそのブラウザですでに Google にログインしている場合は、アプリケーションの承認のみが求められます。まだログインしていない場合は、最初にログイン画面が表示されます。そこでログアウトするだけで、別のユーザーとしてログインできます。

外部ブラウザに依存する代わりに、独自のWebView. Web ビューの Cookie 管理を自分で実装しない場合、ユーザーは常にそこにログインするよう求められます。

于 2012-10-03T17:26:54.177 に答える