Introduction
The goal of this article is to get twitter integration up & running from your Android app in 30 minutes. The guide will show you how to:
setup a twitter test account.
register a twitter application.
authenticate the user in your Android application.
have the user send tweets from your Android application.
The goal of this article is to get twitter integration up & running from your Android app in 30 minutes. The guide will show you how to:- setup a twitter test account.
- register a twitter application.
- authenticate the user in your Android application.
- have the user send tweets from your Android application.
This guide is accompanied by a sample application that’s available in Github in the AndroidTwitterSample repository. To import this project in Eclipse, I suggest using the EGit plugin that can be installed via the Main P2 Repository located at http://download.eclipse.org/egit/updates.
Before running this project, make sure you change the com.ecs.android.sample.twitter.Constants file to include your consumer key and consumer secret. (see subsequent section).
Once you have sample application up & running, you can copy the relevant classes into your projects to have Twitter up & running.
Twitter uses the OAuth protocol to authorize your android application to send tweets on behalf of the end-user. The end-user will need to authenticate against Twitter (meaning that your application will not capture the twitter username / password). Once the user has authorized access, you’ll be able to send tweets on behalf of the user. We’ll use signpost library to handle the OAuth communication, and the Twitter4J library to handle the Twitter specific interactions (sending tweets).
Setting up the Twitter account and application.
We’ll start by setting up a test-account on Twitter that we’ll use in our Android application. Goto the Twitter signup page and create an account. You’ll receive an email from Twitter to confirm your account. You can skip the friends import as it will only be used for testing purposes.Now that we have the Twitter account setup, we need to define an application. Go to the Twitter Application Registration page, and register an application. The application that your register here is required to perform Twitter interaction from your Android application. The Twitter application will have a consumer key and consumer secret associated with it that we’ll use in our Android application.
Fill in the required fields like you can see in the screenshot below:
Once the application is registered, you’ll receive the following information associated with your application :
Consumer key
************************ (masked)
Consumer secret
************************ (masked)
Request token URL
https://api.twitter.com/oauth/request_token
Access token URL
https://api.twitter.com/oauth/access_token
Authorize URL
https://api.twitter.com/oauth/authorize
Registered OAuth Callback URL
http://someurl.com
This is all the information we need to start integrating Twitter in our Android application.
Note : The callback URL specified here is just a required field that we need to fill in, but is not used in our application. Instead, we define our own callback URL that we’ll pass on when authenticating the user.
The sample application
The sample application is available in Github in the AndroidTwitterSample repository. Before running this project, make sure you change the com.ecs.android.sample.twitter.Constants file to include your consumer key and consumer secret. The application provides you with an end-to-end example on how to authenticate against Twitter and send tweets on behalf or the authenticated user.The sample project has a dependency towards the following libraries :
- signpost-commonshttp4-1.2.1.1.jar
- signpost-core-1.2.1.1.jar
- httpclient-4.0.1.jar
- twitter4j-core-2.1.11
The sample application contains 1 main activity with:
- a status message, indicating if you’re logged into Twitter.
- a Tweet button, used to send a Tweet. When not authenticated, the application will redirect you to the Twitter loging page.
- a Clear Credentials button, removing all saved credentials, forcing you to login next time you want to send a Tweet.
The Constants file
The Android project contains a Constants file containing the following information we received from Twitter when we setup our application.1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Constants { public static final String CONSUMER_KEY = "<FILL IN YOUR CONSUMER KEY FROM TWITTER HERE>"; public static final String CONSUMER_SECRET= "<FILL IN YOUR CONSUMER SECRET FROM TWITTER HERE>"; public static final String REQUEST_URL = "http://api.twitter.com/oauth/request_token"; public static final String ACCESS_URL = "http://api.twitter.com/oauth/access_token"; public static final String AUTHORIZE_URL = "http://api.twitter.com/oauth/authorize"; final public static String CALLBACK_SCHEME = "x-latify-oauth-twitter"; final public static String CALLBACK_URL = CALLBACK_SCHEME + "://callback"; } |
Dev note : If you want to integrate Twitter in your own app, I suggest making similar Constants available throughout your application.
What we have defined in the Constants class:
The tweet button
The code behind the Tweet button is implemented like this:1 2 3 4 5 6 7 8 9 10 11 | tweet.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (TwitterUtils.isAuthenticated(prefs)) { sendTweet(); } else { Intent i = new Intent(getApplicationContext(), PrepareRequestTokenActivity.class); i.putExtra("tweet_msg",getTweetMsg()); startActivity(i); } } }); |
From a user experience, we opted to not have a seperate login button, but just have a single Tweet button, and encapsulate the authentication logic inside the Tweet login.
Basically, it performs a check to see if the user has already authenticated to Twitter.
- If not, he’ll be redirected to the twitter login page by popping a browser. Once the user has authenticated, he’ll authorize the Android application to send tweets on the users behalf and the tweet will be sent (notice how we pass the tweet msg to the Intent when starting the PrepareRequestTokenActivity activity).
- If the user was already authenticated before, the tweet will be sent immediately.
Authenticating the user
We’ll start with the first case, where the user hasn’t authenticated to Twitter yet. This is the most complex part, as it involves implementing the OAuth flow to finally retrieve an access token.This complete OAuth implementation is done in the OAuthRequestTokenTask and the PrepareRequestTokenActivity classes.
Before the user can authorize our application to send Tweets on his behalf, we’ll first need to redirect the user to the Twitter login page. This is done through the PrepareRequestTokenActivity. This will kick in the OAuth interactions required for your application to send tweets on behalf of the logged in user.
Dev note: I suggest copying these 2 classes into your own project, as they have been setup in a generic way.
The following table shows you in detail what each class does:
The PrepareRequestTokenActivity activity sets up our OAuth consumer and provider (using the Signpost library), and starts an Asynchronous task called OAuthRequestTokenTask.
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { this.consumer = new CommonsHttpOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET); this.provider = new CommonsHttpOAuthProvider(Constants.REQUEST_URL,Constants.ACCESS_URL,Constants.AUTHORIZE_URL); } catch (Exception e) { Log.e(TAG, "Error creating consumer / provider",e); } Log.i(TAG, "Starting task to retrieve request token."); new OAuthRequestTokenTask(this,consumer,provider).execute(); } |
This asynchronous task just starts an Intent that launches a browser to authenticate the user against Twitter. At this point, our Android application gives control to Twitter. The user enters his username/password, and Twitter will do the authentication. Notice how we also specify a callback URL. Twitter will redirect to this callback URL after the user has properly authenticated against twitter. In our case, the callback URL is x-oauthflow-twitter://callback. This callback is required to give back the control to our Android application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Override protected Void doInBackground(Void... params) { try { Log.i(TAG, "Retrieving request token from Google servers"); final String url = provider.retrieveRequestToken(consumer, Constants.OAUTH_CALLBACK_URL); Log.i(TAG, "Popping a browser with the authorize URL : " + url); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND); context.startActivity(intent); } catch (Exception e) { Log.e(TAG, "Error during OAUth retrieve request token", e); } return null; } |
The twitter login page
In our AndroidManifest.xml, The PrepareRequestTokenActivity, responsible for popping the browser has an intent filter defined with a scheme and host that corresponds to our callback.
1 2 3 4 5 6 7 8 | <activity android:name=".PrepareRequestTokenActivity" android:launchMode="singleTask">> <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> </activity> |
Dev note: You’ll need to include this activity into your own project if you want to enable the Twitter integration.
Due to the fact that we have the intent filter defined we’ll be able to intercept the callback that Twitters sends. So after the user authenticated, Twitter sends a redirect to our callback URL, causing our onNewIntent method to kick in. At this point, we can continue with the OAuth flow and retrieve the access token using the RetrieveAccessTokenTask.
1 2 3 4 5 6 7 8 9 10 11 12 | @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); final Uri uri = intent.getData(); if (uri != null && uri.getScheme().equals(Constants.OAUTH_CALLBACK_SCHEME)) { Log.i(TAG, "Callback received : " + uri); Log.i(TAG, "Retrieving Access Token"); new RetrieveAccessTokenTask(this,consumer,provider,prefs).execute(uri); finish(); } } |
The RetrieveAccessTokenTask is responsible for capuring the access token, required to do communication with Twitter.
It basically extracts the access token from the callback URL, passed on to it from the previous code snippet. We then store the access token and secret in our shared preferences, so that the user doesn’t need to login to Twitter again, not even after restarting the application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | @Override protected Void doInBackground(Uri...params) { final Uri uri = params[0]; final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER); try { provider.retrieveAccessToken(consumer, oauth_verifier); final Editor edit = prefs.edit(); edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken()); edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret()); edit.commit(); String token = prefs.getString(OAuth.OAUTH_TOKEN, ""); String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, ""); consumer.setTokenWithSecret(token, secret); context.startActivity(new Intent(context,AndroidTwitterSample.class)); executeAfterAccessTokenRetrieval(); Log.i(TAG, "OAuth - Access Token Retrieved"); } catch (Exception e) { Log.e(TAG, "OAuth - Access Token Retrieval Error", e); } return null; } |
Notice the executeAfterAccessTokenRetrieval method, that will be executed after having retrieved the access token. We’ll use this hook to actually send the message now.
It basically extracts the tweet message from the Intent that was passed along in the beginning of the OAuth flow (when clicking the Tweet button).
Sending the Tweet
Sending the actual Tweet is via a background thread like this:In order to provide feedback to the user (Toast message), we perform a post to a handler defined in our main Activity.
The actual sending of the Tweet is done through the Twitter4J library, where we retrieve the access token and secret. We set the consumer key, consumer secret and access token on our Twitter object, and call the updateStatus method to send our Tweet.
1 2 3 4 5 6 7 8 9 10 | public static void sendTweet(SharedPreferences prefs,String msg) throws Exception { String token = prefs.getString(OAuth.OAUTH_TOKEN, ""); String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, ""); AccessToken a = new AccessToken(token,secret); Twitter twitter = new TwitterFactory().getInstance(); twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET); twitter.setOAuthAccessToken(a); twitter.updateStatus(msg); } |
After making this call, your Tweet will be visible on your Twitter page:
I ran the sample app in the eclipse and is also connected properly . Its also authenticated and say status as Logged in to twitter:True but i cannot send the tweet message when i click tweet button its not responding . Its staying as it is . Could you please help on this.
ReplyDeleteYou want to change the Read write access for the application in Twitter development site.
Deletesame problem has happened to my application
ReplyDeleteI have found the missing part, default access type should be read & write. If there is only read access, above situation happens
ReplyDeleteThanks for sharing your info. I really appreciate your efforts and I will be waiting for your further write ups thanks once again.
ReplyDeleteRather than opening a browser page (with help of callback url) after successful authentication process, I would like to open an activity of my project. For this, what should I set in the callback url? I had also tried keeping callback_url blank but then where do I set which activity should be opened after the page "redirecting back to your application"?
ReplyDeleteGot the solution so sharing here if someone wants it in future:
ReplyDeleteI had to set twitter_callback_url as "TweetActivity://connect"
where "TweetActivity" is the activity which i wanted to open after successful authentication.
Thanks Anonymous for sharing your knowledge
DeleteHello,
ReplyDeleteI get the following error, anyone can help please:
E/AndroidRuntime(9671): FATAL EXCEPTION: main
E/AndroidRuntime(9671): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.newtest/com.example.newtest}: java.lang.ClassNotFoundException: com.example.newtest
E/AndroidRuntime(9671): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2024)
E/AndroidRuntime(9671): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
E/AndroidRuntime(9671): at android.app.ActivityThread.access$600(ActivityThread.java:140)
E/AndroidRuntime(9671): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
E/AndroidRuntime(9671): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(9671): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(9671): at android.app.ActivityThread.main(ActivityThread.java:4898)
E/AndroidRuntime(9671): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(9671): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(9671): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
E/AndroidRuntime(9671): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
E/AndroidRuntime(9671): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(9671): Caused by: java.lang.ClassNotFoundException: com.example.newtest
E/AndroidRuntime(9671): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
E/AndroidRuntime(9671): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
E/AndroidRuntime(9671): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
E/AndroidRuntime(9671): at android.app.Instrumentation.newActivity(Instrumentation.java:1057)
E/AndroidRuntime(9671): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2015)
check for important android interview questions @ http://skillgun.com
ReplyDeleteThanks for posting useful information.You have provided an nice article, Thank you very much for this one. And i hope this will be useful for many people.. and i am waiting for your next post keep on updating these kinds of knowledgeable things...Really it was an awesome article...very interesting to read..
ReplyDeleteplease sharing like this information......
Android training in chennai
Ios training in chennai
This article is very much helpful and i hope this will be an useful information for the needed one. Keep on updating these kinds of
ReplyDeleteinformative things...
Mobile App Development Company
Mobile App Development Company in India
Mobile App Development Companies