【问题标题】:Twitter Authentication through Android's AccountManager classes通过 Android 的 AccountManager 类进行 Twitter 身份验证
【发布时间】:2011-09-14 12:45:44
【问题描述】:

我正在开发一个 android 应用程序并想集成 Twitter。

我的理解是,如果在用户的设备上安装了官方的 android Twitter 应用程序,那么我们可以使用帐户管理器进行身份验证,名称为 here.. 如果未安装,则显示 twitter 登录网页。

我的理解正确吗?

现在使用 twitter 网络登录页面进行身份验证工作正常。但是如何使用客户经理登录?

使用 AccountsType 作为“com.twitter.android.auth.login” 我使用客户经理从 •com.twitter.android.oauth.token •com.twitter.android.oauth.token.secret

我正在使用 Twitter4J,并使用我的 CONSUMER_KEY 和 CONSUMER_SECRET 以及 recvd 进行身份验证。令牌。但身份验证总是失败。

CONSUMER_KEY 和 CONSUMER_SECRET 是我在 twitter 上注册应用程序时获得的密钥...但我不明白如何将这些密钥用于官方 Android Twitter 应用程序身份验证?

请。告诉我谢谢

这是我的代码

public class TwitterAuthentication {    
    private static final String TAG = "TwitterAuthentication";
    private static final int MSG_GOT_AUTH_TOKEN = 100;
    private static final int MSG_GOT_AUTH_SECRET = 101;
    private static final int MSG_NO_AUT_TOKEN_RECVD = 102;

    public static Twitter mTwitter = null;
    private Activity mActivity = null;
    private SharedPreferences prefs;
    private MessageHandler handler = new MessageHandler();
    public static boolean bAuthenticationDone = false;



    public TwitterAuthentication(Activity activity){
        mActivity = activity;
        prefs = PreferenceManager.getDefaultSharedPreferences(mActivity);
        if (null == mTwitter){
            mTwitter = new TwitterFactory().getInstance();;
            mTwitter.setOAuthConsumer(Constant.CONSUMER_KEY, Constant.CONSUMER_SECRET);
            bAuthenticationDone = false;
        }

    }

    public void LoginTwitter(){
        if (Constants.DEBUG)Log.d(TAG,"LoginTwitter");
        if (bAuthenticationDone){
            TwitterSessionEvents.onLoginSuccess();
        }
        else if (!isSessionValid()){
            AuthTwitter();
        }
        else{

            bAuthenticationDone = true;
            TwitterSessionEvents.onLoginSuccess();
        }       
    }

    public boolean isSessionValid(){
        boolean ret = false;
        if (null != prefs && null != mTwitter){
            String token = prefs.getString(Constant.OAUTH_TOKEN, "");
            String secret = prefs.getString(Constant.OAUTH_TOKEN_SECRET, "");   
            if (null != token && null != secret && token.length()>0 && secret.length()>0){
                AccessToken a = new AccessToken(token,secret);  
                mTwitter.setOAuthAccessToken(a);
                try {
                    mTwitter.getAccountSettings();
                    keys.User_Id = mTwitter.getScreenName();
                    ret = true;
                } catch (TwitterException e) {
                    ret = false;
                }
            }
        }
        return ret;
    }

    public void AuthTwitter(){

        // First check if Account manager has valid token
        // Result of this is send in MSG
        CheckAccManagerForTwitter();

    }


    public Twitter getTwitter(){
        return mTwitter;
    }

    private boolean CheckAccManagerForTwitter(){

        AccountManager am = AccountManager.get(mActivity); 
        Account[] accts = am.getAccountsByType("com.twitter.android.auth.login");
        if(accts.length > 0) {
            Account acct = accts[0];

            am.getAuthToken(acct, "com.twitter.android.oauth.token", null, mActivity, new AccountManagerCallback<Bundle>() {

                @Override
                public void run(AccountManagerFuture<Bundle> arg0) {
                    try {
                        Bundle b = arg0.getResult();
                        String token = b.getString(AccountManager.KEY_AUTHTOKEN);
                        String userName = b.getString(AccountManager.KEY_ACCOUNT_NAME);
                        handler.sendMessage(handler.obtainMessage(MSG_GOT_AUTH_TOKEN, token));
                    }
                    catch (Exception e) {
                        Log.e(TAG, "EXCEPTION@AUTHTOKEN");
                        handler.sendEmptyMessage(MSG_NO_AUT_TOKEN_RECVD);
                    }
                }}, null); 

            am.getAuthToken(acct, "com.twitter.android.oauth.token.secret", null, mActivity, new AccountManagerCallback<Bundle>() {

                    @Override
                    public void run(AccountManagerFuture<Bundle> arg0) {
                        try {
                            Bundle b = arg0.getResult();
                            String secret = b.getString(AccountManager.KEY_AUTHTOKEN);
                            handler.sendMessage(handler.obtainMessage(MSG_GOT_AUTH_SECRET,secret));

                            }
                        catch (Exception e) {
                            Log.e(TAG, "EXCEPTION@AUTHTOKEN");
                            handler.sendEmptyMessage(MSG_NO_AUT_TOKEN_RECVD);
                            }
                        }}, null); 
                //
        }
        else{
            // No twitter account found in Account Manager
            Log.e(TAG, "No Twitter account in Account manager");
            handler.sendEmptyMessage(MSG_NO_AUT_TOKEN_RECVD);

        }

        return true;
        }

    class MessageHandler extends Handler {
        String token = null;
        String secret = null;
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == MSG_GOT_AUTH_TOKEN | msg.what ==MSG_GOT_AUTH_SECRET){
                if (msg.what == MSG_GOT_AUTH_TOKEN){        
                    token = (String)msg.obj;
                }
                else if (msg.what == MSG_GOT_AUTH_SECRET){
                    secret = (String)msg.obj;
                }
                if (null != token && null != secret){
                    AccessToken accesstoken = new AccessToken(token,secret);
                    mTwitter.setOAuthAccessToken(accesstoken);
                    try {
                        mTwitter.getAccountSettings();
                        keys.User_Id = mTwitter.getScreenName();                    
                    } catch (Exception e) {
                        // That means Authentication Failed
                        // So fall back to web login 
                        Intent i = new Intent(mActivity.getApplicationContext(), PrepareRequestTokenActivity.class);
                        mActivity.startActivity(i);                 
                    }
                }

            }
            else if (msg.what == MSG_NO_AUT_TOKEN_RECVD){
                // That means There is no twiter account with Account Manager
                // So fall back to web login 
                Intent i = new Intent(mActivity.getApplicationContext(), PrepareRequestTokenActivity.class);
                mActivity.startActivity(i);                 
            }
        }
    }



    public void LogoutTwiter(){


    }

}

【问题讨论】:

    标签: android authentication twitter accountmanager


    【解决方案1】:

    Android 的 AccountManager 返回的 com.twitter.android.oauth.tokencom.twitter.android.oauth.token.secret 凭据仅使用 Twitter 的官方 Consumer Key 和 Secret 进行身份验证。 AFAIK 它们实际上对第三方开发人员没有用。

    关于 Twitter,我只想说官方的 Consumer Key/Secret 对“已经存在”,如果 Twitter 通过应用更新更改它们,他们会在没有应用更新的情况下破坏每个用户的 OAuth。

    【讨论】:

      【解决方案2】:

      您使用密钥和使用者密钥来实际获取令牌。通过使用 android 帐户,您可以从他们那里获得令牌。

      因此,一般来说,例如,您只需要一个令牌,正如我所说,您可以从帐户或 twitter4j 获得该令牌。因此,在您从帐户中获取令牌后,您需要将其设置为您的 twitter 4jsdk 令牌并定期使用该 API。

      希望这是有道理的。

      【讨论】:

      • @DArko 感谢您的回复,我明白您的意思,但问题是在 Twitter4J 中我将其设置为 AccessToken 时,出现异常 oAuth fail。
      • @DArko 我在我的帖子中添加了代码,只是为了展示我在做什么,请。让我知道我错在哪里。
      • 您是否尝试记录您收到的令牌?也许尝试使用浏览器中的令牌,看看它是否有效或至少是否正确接收。据我所知,代码似乎很好..
      • 我的理解是使用 4 个不同的密钥,即消费者密钥、秘密密钥、访问令牌和秘密令牌,所有其他详细信息都像用户名或屏幕名称一样计算。当我使用我的消费者密钥和秘密密钥通过网络浏览器使用时,我接收到不同的访问令牌和 sekret 令牌,并且工作正常。但是,如果我从客户经理那里使用访问令牌和 Twitter 应用程序的秘密令牌,而不是计算屏幕名称等其他详细信息......所以我认为使用客户经理令牌我应该知道 Android 推特应用程序的消费者密钥和秘密密钥,这显然是我没有。
      • 阅读有关 oAuth 的信息。我建议在标记下的文字。 stackoverflow.com/questions/3514579/….
      猜你喜欢
      • 2015-09-12
      • 2015-06-03
      • 2012-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-26
      • 1970-01-01
      相关资源
      最近更新 更多