【问题标题】:Problem in Callback in Twitter in AndroidAndroid 中 Twitter 回调中的问题
【发布时间】:2011-10-12 10:36:27
【问题描述】:

我已经在我的应用程序中实现了 Twitter,我在回调中遇到了问题。

Twitter API 最近更新了,所以我无法发送回调 URL。

现在设置页面也发生了变化,没有选择基于 Web 的应用程序或桌面应用程序的选项。

如果我在这一行发送回调:

authUrl = provider.retrieveRequestToken(consumer,CALLBACK_URL);

它总是返回

oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match.

但如果我在此 重定向到 Twitter 登录页面中发送 Null,但在成功授权后它不会返回到我的应用程序。

显示 Pin 号码后,我想重定向回我的应用程序。

注意:Twitter 已更新其 API,因此帖子中可用的旧代码无法正常工作。

我尝试了所有以下链接

Link 1, Link 2, Link 3, Link4 , Link5 , Link 6

我的代码如下:

public class Main extends Activity {
OAuthConsumer consumer;
OAuthProvider provider;
Twitter twitter;
private static  String CALLBACK_URL = "twitterapptest://connect";


@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.main);

    consumer = new DefaultOAuthConsumer(
            "XXXXXXXXXXX",
            "XXXXXXXXXXXXX");

    provider = new DefaultOAuthProvider(
            "https://api.twitter.com/oauth/request_token",
            "https://api.twitter.com/oauth/access_token",
            "https://api.twitter.com/oauth/authorize");

    String authUrl = null;
    try {
        authUrl = provider.retrieveRequestToken(consumer,null);
         this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
    } catch (OAuthMessageSignerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthNotAuthorizedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthExpectationFailedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthCommunicationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String pin = null;
    try {
        pin = br.readLine();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        provider.retrieveAccessToken(consumer, "4947222");
    } catch (OAuthMessageSignerException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthNotAuthorizedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthExpectationFailedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (OAuthCommunicationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    URL url = null;
    try {
        url = new URL("http://twitter.com/statuses/mentions.xml");
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    HttpURLConnection request = null;
    try {
        request = (HttpURLConnection) url.openConnection();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        consumer.sign(request);
    } catch (OAuthMessageSignerException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (OAuthExpectationFailedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (OAuthCommunicationException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    try {
        request.connect();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        System.out.println("Response: " + request.getResponseCode() + " "
                + request.getResponseMessage());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


/**
 * As soon as the user successfully authorized the app, we are notified
 * here. Now we need to get the verifier from the callback URL, retrieve
 * token and token_secret and feed them to twitter4j (as well as
 * consumer key and secret).
 */

     @Override
    protected void onNewIntent(Intent intent) {

        super.onNewIntent(intent);

        Uri uri = intent.getData();
        if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {

            String verifier = uri
                    .getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);

            try {
                // this will populate token and token_secret in consumer

                provider.retrieveAccessToken(consumer,
                        verifier);

                // TODO: you might want to store token and token_secret in you
                // app settings!!!!!!!!

                AccessToken a = new AccessToken(consumer.getToken(),
                        consumer.getTokenSecret());

                // initialize Twitter4J

                twitter = new TwitterFactory().getInstance();
                twitter.setOAuthConsumer("XXXXXXX", "XXXXXXXXXX");
                twitter.setOAuthAccessToken(a);

                // create a tweet

                Date d = new Date(System.currentTimeMillis());
                String tweet = "#OAuth working! " + d.toLocaleString();

                // send the tweet

                twitter.updateStatus(tweet);

            } catch (Exception e) {

                Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }
    }
}

我的清单:

<?xml version="1.0" encoding="utf-8"?>

    <activity android:name=".OAuthForTwitter"  android:label="@string/app_name"
            android:configChanges="orientation|keyboardHidden"  android:launchMode="singleInstance">
     <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:scheme="twitterapptest" android:host="connect" />
    </intent-filter>

</activity>

</application>
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.INTERNET" />

【问题讨论】:

  • 401 错误可能是由多种原因引起的。特别要检查您的 API 密钥是否正确(没有多余的空格或缺少字符),并检查您设备上的日期/时间和时区是否正确。
  • @Dave 你在你的应用程序中使用过 Twitter 吗?

标签: android twitter twitter-oauth


【解决方案1】:

问题在于回调 URl。 我们应该在应用程序设置页面的回调 URL 的字段名称中给出一个 Dummy Callback URL。

如果我们这样做并在我们的代码中发送回调 URL,成功登录后将有一个名为重定向到您的应用程序

的选项

更多参考请查看Link for Twitter

【讨论】:

  • 链接不再起作用。我的重定向有问题。使用 localhost 作为重定向 url 显示了 localhost 的网页。它没有向我的应用程序返回任何建议?
【解决方案2】:

你找到问题的根源了吗?我有同样的一个例外,最后我找到了它的来源。 Twitter的设置页面发生了变化,您不能再选择基于Web的应用程序或桌面应用程序。但这里有一些提示:在你的 Twitter 应用程序的设置中,只需用一个像 http://www.dummy.com 这样的虚拟 URL 填充回调 URL。这将隐式设置您的应用程序具有 Web 浏览器,然后当您发送自己的回调时,它将替换虚拟的。 我花了很多时间才找到这个,所以我希望这个答案会对某人有所帮助。

【讨论】:

    【解决方案3】:

    在应用程序中添加以下Callback URL 将解决问题。它将用户重定向到Application,这将启动它来验证用户的Twitter帐户_

    更新Manifest_

    <activity android:name="<YOUR ACTIVITY NAME>"
            android:launchMode="singleTask" android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:screenOrientation="portrait">
            <intent-filter>
                <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:scheme="x-oauthflow-twitter" android:host="callback" />
            </intent-filter>
    

    在您的TwitterManager 中,您拥有所有TwitterFactory 和所需的东西_

    final public static String  CALLBACK_SCHEME = "x-oauthflow-twitter";    
    final public static String  CALLBACK_URL = CALLBACK_SCHEME + "://callback";
    public static final String TWITTER_IEXTRA_OAUTH_VERIFIER = "oauth_verifier";
    

    你终于可以得到你需要的一切_ 例如,getHostgetSchemegetEncodedQuerygetQuerygetEncodedSchemeSpecificPart 等根据您的需要使用由回调返回的 intent_

    @Override
    protected void onNewIntent(final Intent intent) {
        super.onNewIntent(intent);
    
        new AsyncTask<Void,Void,Void>(){
            @Override
            protected Void doInBackground(Void... arg0) {
                Uri uri = intent.getData();
                if (uri != null && uri.toString().startsWith(TwitterManager.TWITTER_CALLBACK_URL)) {
                    String verifier = uri.getQueryParameter(TwitterManager.TWITTER_IEXTRA_OAUTH_VERIFIER);
                    Log.e("---ActivityMain-onNewIntent---", "verifier:"+verifier+", uri- getQuery:"+uri.getQuery());
                    Log.i(ApplicationPockets.TAG, "verifier : "+verifier);
                    if(verifier != null){
                        try {
                         /*
                          *---Get the AccessToken and do what you like ... :)
                          */
                            AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, verifier);
                           SharedPreferences.Editor e = context.getSharedPreferences(SF_TWITTER, Context.MODE_PRIVATE).edit();
                           e.putString(TWITTER_PREF_KEY_TOKEN, accessToken.getToken());
                           e.putString(TWITTER_PREF_KEY_SECRET, accessToken.getTokenSecret());
                          e.commit();
                         //Extra you would like to do...
                        } catch (TwitterException e) {
                            e.printStackTrace();
                        }
                    }else{
                        //Logout Twitter.
                    }
                }
                return null;
            }
        }.execute();
    }
    

    你的 RequestToken_

      try {
             RequestToken requestToken = twitter.getOAuthRequestToken(TWITTER_CALLBACK_URL);
            //Toast.makeText(activity, "Please authorize this app!", Toast.LENGTH_LONG).show();
            activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(requestToken.getAuthenticationURL())));
          } catch (TwitterException e) {
    
              e.printStackTrace();
        }
    

    希望对大家有所帮助_

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-18
      • 1970-01-01
      • 2014-07-23
      • 2013-07-08
      • 1970-01-01
      • 2011-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多