4

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, Link 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" /> 

2
  • The 401 error can be caused by several things. In particular, check your API keys are correct (no extra spaces or missing characters), and also check that the date/time and timezone on your device are correct. Commented Jul 25, 2011 at 12:30
  • @Dave Have u used Twitter in Your Application? Commented Jul 25, 2011 at 13:13

3 Answers 3

8

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

Sign up to request clarification or add additional context in comments.

1 Comment

link doesn't work any more. I have a problem with the redirection. Using the localhost as redirect url shows me the web page of the localhost. It doesn't return to my application any suggestion?
3

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.

Comments

0

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_

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.