开发者

Problem in Callback in Twitter in Android

I have implemented Twitter in my application , i am facing problem in Callback.

Twitter API's has been updated recently so i am unable to send Callback URL.

Also the Setting Page now change there is No Option for Selecting Web Based application or Desktop Application.

If i send Callback in this Line :

authUrl = provider.retrieveRequestToken(consumer,CALLBACK_URL);

It always returns

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.

but if i send as Null in this its Redirecting to Twitter Login Page,but after successful Authorization it doesn't returns back to my Application.

After the Pin number is displayed i want to Redirect back to my Application.

Note : Twitter had updated their API so old Codes available in the Post is not working.

I tried all the Following Links

Link 1, L开发者_开发技巧ink 2, Link 3, Link4 , Link5 , Link 6

My Code is as follows :

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

My Manifest :

<?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" />


The problem is that Callback URl. We should give one Dummy Callback URL in the Field Name of CallBack URL in Application' s Settings Page.

If we do like that and send the Call Back URL in our code, after successful Login there will be a option called Redirecting to your Application

For Further Reference check this Link for Twitter


Have you found where the problem come from? I had the same one exeception and finally I found where this come from. That right that the setting page of Twitter had change and you can't no more selecting Web Based application or Desktop Application. But here is the tips: in settings of your Twitter application just fill the Callback URL with a dummy one like http://www.dummy.com . This will implicitly set your application has a web browser and then when you send your own callback it will remplace the dummy one. I had spend a lot of times to find this so I hope this answer will help someone.


Adding the below Callback URL in to app would solve the problem. It will redirect user to the Application which start it to authenticate user's Twitter account_

update in 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>

In Your TwitterManager where you have all your TwitterFactory and the required things_

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";

Finally you can get everything that you need_ e.g., getHost, getScheme, getEncodedQuery, getQuery, getEncodedSchemeSpecificPart and more as per your need using the intent that return by the call back_

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

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

I hope this will help everyone_

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜