Twitter Authentication through Android's AccountManager classes
Asked Answered
M

2

7

I am developing an android application and want to integrate Twitter.

What I understand is if on user's device, official android Twitter app is installed then we can authenticate using account manager as mentined here.. and if not installed then show twitter login web page.

Is my understanding correct?

Now authenticating using twitter web login page is working fine. But how do I login using account manager?

Using AccountsType as "com.twitter.android.auth.login" I got token and token secret using account manager from •com.twitter.android.oauth.token •com.twitter.android.oauth.token.secret

I am using Twitter4J, and authenticating with my CONSUMER_KEY & CONSUMER_SECRET along with recvd. tokens. but authentication always fails.

CONSUMER_KEY & CONSUMER_SECRET are the keys I got when I registered the app at twitter... but I dont understand how can I use these keys with Official Android Twitter app authentication?

Pls. let me know Thanks

Here is my code

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(){


    }

}
Multinational answered 14/6, 2011 at 8:49 Comment(0)
P
3

The com.twitter.android.oauth.token and com.twitter.android.oauth.token.secret credentials returned by Android's AccountManager only authenticate using Twitter's official Consumer Key and Secret. AFAIK They're not actually useful to third party developers.

With respect to Twitter I'll just say the official Consumer Key/Secret pair is "out there", and if Twitter changed them via an app update they'd break OAuth for every user without that app update.

Platter answered 9/7, 2013 at 18:43 Comment(0)
C
1

well you use the secret and consumer key to actually get a token. by using the android accounts you get the token from them.

So in general to do a tweet for example you only need a token and as i said you get that one either from the accounts or from twitter4j. so after you get the token from the accounts you need to set it as your twitter 4jsdk token and use the api regularly.

Hope this makes sense.

Cupro answered 14/6, 2011 at 8:59 Comment(9)
@DArko Thanks for your response, I understand what you say, but the problem is when in Twitter4J I set that as AccessToken, I get exception oAuth fail.Multinational
@DArko I have added code in my post, just to show what I am doing, Pls. let me know where I am wrong.Multinational
did you try to log the token that you are receiving? maybe try to use the token from a browser maybe, see if it is valid or something or at least if it is correctly received. The code seems to be fine as much as i can tell..Cupro
What I understand is using 4 different keys that is Consumer key, Secret Key , Access token and Secret token all other details are computed like username or screen name. When I use via web browser using my consumer key and secret key i recv diferent access token and sekret token and that works fine. But if I user access token and secret token of Twitter app from account manager than other details like screen name is not computed... So i think to use account manager token i should know consumer key and secret key of Android twiter app which obvisously i dont have.Multinational
Read this about oAuth. i suggest the text below the marked one. #3515079.Cupro
So this means that you can get the token and token.secret from the account manager and use them. but the issue here is if it is possible to use those things in combination with your apps secret and key. in my logic i don't think it is because the token is acutally signed with different key pairs. i don't know exactly how the twitter api works but if it needs sending all 4 of the params you mentioned then you cant use the token from the account manager..Cupro
dev.bostone.us/2009/07/16/android-oauth-twitter-updates/… also this states that you just need to sign a request with the token and token secret to get a response from the api. so sending a request from only the account info is certainly possible.Cupro
so does that mean info recvd. from account manager can not be used anyway?Multinational
well that means no they can't as far as i can tell, because you don't have the secret and consumer keys. this is news to me also :D. i hope we will hear from someone that has more experience in this matter. i have never tried using the keys from the account manager for twitter.Cupro

© 2022 - 2024 — McMap. All rights reserved.