Twitter OAuth身份验证回调无效 - Twitter4J

时间:2014-02-24 00:47:07

标签: android twitter oauth android-activity twitter4j

首先,我至少两次查看了本网站上有关该主题的每个问题,但我找不到任何内容。

我已经使用了一些教程来创建一个只提供OAuth登录的Twitter4J的简单Twitter客户端。代码将用户带到浏览器,接受OAuth,然后浏览器将我返回到我的应用程序。

但是,我无法使用方法getOAuthAccessToken()中的onNewIntent(Intent intent)方法获取OAuth访问令牌,并且日志显示错误只是Twitter Login Error > null

我尝试使用onResume,onNewIntent更改getOAuthAccessToken()的位置,我已将Activity设置为singleInstance和singleTask,并且我已正确设置日期和时间。如果有人可以帮助我从浏览器返回时从Twitter获取访问令牌,那将是非常好的,谢谢!这是我的代码:

public class mAppActivity extends Activity {

    // constants
    static final String TWITTER_CONSUMER_KEY = "";
    static final String TWITTER_CONSUMER_SECRET = 
            "";

    // preference constants
    static final String PREFERENCE_NAME = "twitter_oauth";
    static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
    static final String PREF_KEY_OAUTH_SECRET = "oauth_token_secret";
    static final String PREF_KEY_TWITTER_LOGIN = "isTwitterLoggedIn";

    static final String TWITTER_CALLBACK_URL = "callback://x-oauthflow-twitter";

    // Twitter OAuth URLS
    static final String URL_TWITTER_AUTH = "auth_url";
    static final String URL_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
    static final String URL_TWITTER_OAUTH_TOKEN = "oauth_token";

    // Buttons
    Button btnLoginTwitter;
    Button btnUpdateStatus;
    Button btnLogoutTwitter;

    // EditText for update
    EditText txtUpdate;

    // lbl update
    TextView lblUpdate;
    TextView lblUserName;

    // ProgressDialog
    ProgressDialog pdialog;

    // Twitter 
    private static Twitter twitter;
    private static RequestToken requestToken;
    private AccessToken accessToken;

    // SharedPreferences
    private static SharedPreferences mSharedPreferences;

    // Internet ConnectionDetector
    private ConnectionDetector cd;

    // AlertDialogManager
    AlertDialogManager alert = new AlertDialogManager();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_app_m);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        cd = new ConnectionDetector(getApplicationContext());

        // check if connected to Internet
        if (!cd.isConnectingToInternet()) {
            // show error message
            alert.showAlertDialog(mAppActivity.this, 
                    "Internet Connection Error", 
                    "Please connect to working Internet connection", 
                    false);
            // stop code by returning
            return;
        }

        // check if Twitter keys are set
        if (TWITTER_CONSUMER_KEY.trim().length() == 0 ||
            TWITTER_CONSUMER_SECRET.trim().length() == 0) {
            // show error message
            alert.showAlertDialog(mAppActivity.this, 
                    "Twitter OAuth Tokens Error",
                    "Please set your Twitter OAuth tokens first!", 
                    false);

            // stop code by returning
            return;
        }

        // All UI elements
        btnLoginTwitter = (Button) findViewById(R.id.btnLoginTwitter);
        btnUpdateStatus = (Button) findViewById(R.id.btnUpdateStatus);
        btnLogoutTwitter = (Button) findViewById(R.id.btnLogoutTwitter);
        txtUpdate = (EditText) findViewById(R.id.txtUpdateStatus);
        lblUpdate = (TextView) findViewById(R.id.lblUpdate);
        lblUserName = (TextView) findViewById(R.id.lblUserName);

        // SharedPreferences
        mSharedPreferences = getApplicationContext()
                            .getSharedPreferences("MyPrefs", 0);

        /**
         * Twitter login button click event 
         * will call loginToTwitter() function 
         */
        btnLoginTwitter.setOnClickListener(new View.OnClickListener() {

            @Override 
            public void onClick(View arg0) {
                // Call Twitter login function
                loginToTwitter();
            }
        });

        /**
         * Twitter logout button click 
         */
        btnLogoutTwitter.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // call Twitter logout function
                logoutFromTwitter();
            }
        });            
    }

    /**
     * Function to log in to Twitter
     */
    private void loginToTwitter() {

        // Check if already logged in
        if (!isTwitterLoggedInAlready()) {
            ConfigurationBuilder builder = new ConfigurationBuilder();
            builder.setUseSSL(true);
            builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
            builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
            Configuration configuration = builder.build();

            TwitterFactory factory = new TwitterFactory(configuration);
            twitter = factory.getInstance();

            Thread thread = new Thread(new Runnable(){
                @Override
                public void run() {
                    try {

                        requestToken = twitter
                                .getOAuthRequestToken(TWITTER_CALLBACK_URL);
                        mAppActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
                                .parse(requestToken.getAuthenticationURL())));

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.start();

        } else {
            // user is already logged in into Twitter
            Toast.makeText(getApplicationContext(),
                    "Already Logged into Twitter", Toast.LENGTH_LONG).show();
        }
    }

    /**
     * Checks if user is already logged in using Twitter login 
     * fetched from Shared Preferences
     */
    private boolean isTwitterLoggedInAlready() {
        // return Twitter login status from SharedPreferences
        return mSharedPreferences.getBoolean(PREF_KEY_TWITTER_LOGIN, false); 
    }

    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        /** 
         * This if condition is tested user is 
         * redirected from Twitter page. Parse the URI to OAuth Verifier
         */
        Uri uri = intent.getData();

        Toast.makeText(getApplicationContext(),
                uri.toString(), Toast.LENGTH_LONG).show(); 

        if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL)) {   

            // OAuth verifier 
            final String verifier = uri
                    .getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);

            try {                           
                // get the access token
                        mAppActivity.this.accessToken = 
                                twitter.getOAuthAccessToken(
                                requestToken);

                        // SharedPreferences
                Editor e = mSharedPreferences.edit();

                // after getting access token, access token secret
                // store them in application preferences
                e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
                e.putString(PREF_KEY_OAUTH_SECRET, 
                        accessToken.getTokenSecret());

                // store login status - true
                e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
                e.commit(); // save changes

                Log.e("Twitter OAuth Token", "> " + accessToken.getToken());

                // hide login button
                btnLoginTwitter.setVisibility(View.GONE);

                // show update Twitter
                lblUpdate.setVisibility(View.VISIBLE);
                txtUpdate.setVisibility(View.VISIBLE);
                btnUpdateStatus.setVisibility(View.VISIBLE);
                btnLogoutTwitter.setVisibility(View.VISIBLE);

                // get user details from Twitter
                // for now only username is being gotten
                long userID = accessToken.getUserId();
                User user = twitter.showUser(userID);
                String username = user.getName();

                // display in xml ui 
                lblUserName.setText(Html.fromHtml("<b>Welcome " + username + "</b>"));
            } catch (Exception e) {
                // catch log for login errors
                Log.e("Twitter Login Error", "> " + e.getMessage());
            }                
        }
    }

}

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.messagingapplication"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <!-- Permission - Internet Connect -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- Network State Permissions -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />


    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.messagingapplication.mAppActivity"
            android:label="@string/app_name"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data
                    android:host="x-oauthflow-twitter"
                    android:scheme="callback" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.messagingapplication.MAppMainActivity"
            android:label="@string/title_activity_mapp_main" >
        </activity>
        <activity
            android:name="com.example.messagingapplication.Teest"
            android:label="@string/title_activity_teest" >
        </activity>
    </application>

</manifest>

3 个答案:

答案 0 :(得分:0)

您需要传入OAuth验证程序字符串,该字符串已从查询参数中检索但未正确传递到getOAuthAccessToken方法:

        // OAuth verifier 
        final String verifier = uri
                .getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);

        try {                           
            // get the access token
                    mAppActivity.this.accessToken = 
                            twitter.getOAuthAccessToken(
                            requestToken,
                            verifier); // You forgot to pass this in.

答案 1 :(得分:0)

我解决了同样的问题。它阻止了你的ui。你只需在asynctask中尝试一下。你只需在asynctask中调用该代码。

requestToken = twitter.getOAuthRequestToken(TWITTER_CALLBACK_URL); 或

像这样,

class TwitterLogin extends AsyncTask<String, String, String> 
    {

        @Override
        protected String doInBackground(String... params) 
        {
            // TODO Auto-generated method stub

            Uri uri = getIntent().getData();                
            if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL))
            {
                String verifier = uri.getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);
                try 
                {
                    AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, verifier);
                    // Shared Preferences
                    Editor e = loginPrefs.edit();
                    e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
                    e.putString(PREF_KEY_OAUTH_SECRET,accessToken.getTokenSecret());
                    e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
                    e.commit();

                    Log.e("Twitter OAuth Token", "> " + accessToken.getToken());


                    long userID = accessToken.getUserId();
                    User user = twitter.showUser(userID);
                    String username = user.getName();
                    Log.e("UserID: ", "userID: "+userID+""+username);

                    Log.v("Welcome:","Thanks:"+Html.fromHtml("<b>Welcome " + username + "</b>"));
                } 
                catch (Exception e) 
                {
                    Log.e("Twitter Login Error", "> " + e.getMessage());
                }
            }

            return null;
        }

        @Override
        protected void onPostExecute(String result) 
        {
            // TODO Auto-generated method stub
            super.onPostExecute(result);

        }

        @Override
        protected void onPreExecute() 
        {
            // TODO Auto-generated method stub
            super.onPreExecute();

        }
    }

答案 2 :(得分:0)

问题我认为你在移动设备中运行应用程序而不是模拟器,你需要添加线程来获取来自Twitter CallBack的响应