[TUT] Sending a Tweet

By blundell  blog.blundell-apps.com/sending-a-tweet/

Tweet

Implemented this myself so thought I would share.
This isn’t the prettiest solution but it gives you all the facts and is nice an quick.
I’ve kept it all in one Activity to try and give you the overview you can deal with the OO later yourself.

Source file downloads are at the bottom of this post.

Ok What we are going to do:

Authorise your app to use a users twitter account.
Send a tweet from this account.

Workflow:

User presses Login Button
Checks if user has logged in before
Twitter webpage is opened
User logins in to twitter
App is then allowed to post tweets
Users presses Tweet Button
Tweet is sent to Twitter
Simple!

A sneak preview of what it’ll look like:

spacer
spacer
spacer
spacer

Setup:

You need to create a Twitter Application (takes 2 mins) on the Twitter site: https://dev.twitter.com/apps/

Just like this :
spacer

Ensure
Application Type: Browser
Permissions: Read & Write
Callback URL; doesnt matter put anything google.com

Next you need the Twitter4j Jar, this does all the hard work behind the scenes.

You can download it here: Twitter4J jar

Unzip it.
You then have to add it to your project.

Eclipse:
Right Click on your project > Properties > Java Build Path > Add External Jars > twitter4j-core-android-2.2.3.jar> OK

Easy!

Ok now to the coding!

First your manifest needs to be able to receive the twitter call back from the browser, it also needs the activity to be single instance:

<?xml version="1.0" encoding="utf-8"?>
<manifest
        xmlns:android="schemas.android.com/apk/res/android"
        package="com.blundell.tut.ttt"
        android:versionCode="1"
        android:versionName="1.0">
        <uses-sdk
                android:minSdkVersion="4" />

        <!-- used by twitter integration -->
        <uses-permission
                android:name="android.permission.INTERNET" />

        <application
                android:icon="@drawable/icon"
                android:label="@string/app_name">
                <activity
                        android:name=".TweetToTwitterActivity"
                        android:label="@string/app_name"
                        android:launchMode="singleInstance">
                        <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:scheme="tweet-to-twitter-blundell-01-android" />
                        </intent-filter>
                </activity>

        </application>
</manifest>

Then I’ve compacted it all into a single Activity with comments so you should be able to understand what is going on:

package com.blundell.tut.ttt;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.Toast;

public class TweetToTwitterActivity extends Activity {

        private static final String TAG = "Blundell.TweetToTwitterActivity";

        /** Name to store the users access token */
        private static final String PREF_ACCESS_TOKEN = "accessToken";
        /** Name to store the users access token secret */
        private static final String PREF_ACCESS_TOKEN_SECRET = "accessTokenSecret";
        /** Consumer Key generated when you registered your app at https://dev.twitter.com/apps/ */
        private static final String CONSUMER_KEY = "yourConsumerKey";
        /** Consumer Secret generated when you registered your app at https://dev.twitter.com/apps/  */
        private static final String CONSUMER_SECRET = "yourConsumerSecret"; // XXX Encode in your app
        /** The url that Twitter will redirect to after a user log's in - this will be picked up by your app manifest and redirected into this activity */
        private static final String CALLBACK_URL = "tweet-to-twitter-blundell-01-android:///";
        /** Preferences to store a logged in users credentials */
        private SharedPreferences mPrefs;
        /** Twitter4j object */
        private Twitter mTwitter;
        /** The request token signifies the unique ID of the request you are sending to twitter  */
        private RequestToken mReqToken;

        private Button mLoginButton;
        private Button mTweetButton;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                Log.i(TAG, "Loading TweetToTwitterActivity");
                setContentView(R.layout.main);

                // Create a new shared preference object to remember if the user has
                // already given us permission
                mPrefs = getSharedPreferences("twitterPrefs", MODE_PRIVATE);
                Log.i(TAG, "Got Preferences");

                // Load the twitter4j helper
                mTwitter = new TwitterFactory().getInstance();
                Log.i(TAG, "Got Twitter4j");

                // Tell twitter4j that we want to use it with our app
                mTwitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
                Log.i(TAG, "Inflated Twitter4j");

                mLoginButton = (Button) findViewById(R.id.login_button);
                mTweetButton = (Button) findViewById(R.id.tweet_button);
        }

        /**
         * Button clickables are declared in XML as this projects min SDK is 1.6</br> </br>
         * Checks if the user has given this app permission to use twitter
         * before</br> If so login and enable tweeting</br>
         * Otherwise redirect to Twitter for permission
         *
         * @param v the clicked button
         */
        public void buttonLogin(View v) {
                Log.i(TAG, "Login Pressed");
                if (mPrefs.contains(PREF_ACCESS_TOKEN)) {
                        Log.i(TAG, "Repeat User");
                        loginAuthorisedUser();
                } else {
                        Log.i(TAG, "New User");
                        loginNewUser();
                }
        }

        /**
         * Button clickables are declared in XML as this projects min SDK is 1.6</br> </br>
         *
         * @param v the clicked button
         */
        public void buttonTweet(View v) {
                Log.i(TAG, "Tweet Pressed");
                tweetMessage();
        }

        /**
         * Create a request that is sent to Twitter asking 'can our app have permission to use Twitter for this user'</br>
         * We are given back the {@link mReqToken}
         * that is a unique indetifier to this request</br>
         * The browser then pops up on the twitter website and the user logins in ( we never see this informaton
         * )</br> Twitter then redirects us to {@link CALLBACK_URL} if the login was a success</br>
         *
         */
        private void loginNewUser() {
                try {
                        Log.i(TAG, "Request App Authentication");
                        mReqToken = mTwitter.getOAuthRequestToken(CALLBACK_URL);

                        Log.i(TAG, "Starting Webview to login to twitter");
                        WebView twitterSite = new WebView(this);
                        twitterSite.loadUrl(mReqToken.getAuthenticationURL());
                        setContentView(twitterSite);

                } catch (TwitterException e) {
                        Toast.makeText(this, "Twitter Login error, try again later", Toast.LENGTH_SHORT).show();
                }
        }

        /**
         * The user had previously given our app permission to use Twitter</br>
         * Therefore we retrieve these credentials and fill out the Twitter4j helper
         */
        private void loginAuthorisedUser() {
                String token = mPrefs.getString(PREF_ACCESS_TOKEN, null);
                String secret = mPrefs.getString(PREF_ACCESS_TOKEN_SECRET, null);

                // Create the twitter access token from the credentials we got previously
                AccessToken at = new AccessToken(token, secret);

                mTwitter.setOAuthAccessToken(at);

                Toast.makeText(this, "Welcome back", Toast.LENGTH_SHORT).show();

                enableTweetButton();
        }

        /**
         * Catch when Twitter redirects back to our {@link CALLBACK_URL}</br>
         * We use onNewIntent as in our manifest we have singleInstance="true" if we did not the
         * getOAuthAccessToken() call would fail
         */
        @Override
        protected void onNewIntent(Intent intent) {
                super.onNewIntent(intent);
                Log.i(TAG, "New Intent Arrived");
                dealWithTwitterResponse(intent);
        }

        @Override
        protected void onResume() {
                super.onResume();
                Log.i(TAG, "Arrived at onResume");
        }

        /**
         * Twitter has sent us back into our app</br>
         * Within the intent it set back we have a 'key' we can use to authenticate the user
         *
         * @param intent
         */
        private void dealWithTwitterResponse(Intent intent) {
                Uri uri = intent.getData();
                if (uri != null && uri.toString().startsWith(CALLBACK_URL)) { // If the user has just logged in
                        String oauthVerifier = uri.getQueryParameter("oauth_verifier");

                        authoriseNewUser(oauthVerifier);
                }
        }

        /**
         * Create an access token for this new user</br>
         * Fill out the Twitter4j helper</br>
         * And save these credentials so we can log the user straight in next time
         *
         * @param oauthVerifier
         */
        private void authoriseNewUser(String oauthVerifier) {
                try {
                        AccessToken at = mTwitter.getOAuthAccessToken(mReqToken, oauthVerifier);
                        mTwitter.setOAuthAccessToken(at);

                        saveAccessToken(at);

                        // Set the content view back after we changed to a webview
                        setContentView(R.layout.main);

                        enableTweetButton();
                } catch (TwitterException e) {
                        Toast.makeText(this, "Twitter auth error x01, try again later", Toast.LENGTH_SHORT).show();
                }
        }

        /**
         * Allow the user to Tweet
         */
        private void enableTweetButton() {
                Log.i(TAG, "User logged in - allowing to tweet");
                mLoginButton.setEnabled(false);
                mTweetButton.setEnabled(true);
        }

        /**
         * Send a tweet on your timeline, with a Toast msg for success or failure
         */
        private void tweetMessage() {
                try {
                        mTwitter.updateStatus("Test - Tweeting with @Blundell_apps #AndroidDev Tutorial using #Twitter4j blog.blundell-apps.com/sending-a-tweet");

                        Toast.makeText(this, "Tweet Successful!", Toast.LENGTH_SHORT).show();
                } catch (TwitterException e) {
                        Toast.makeText(this, "Tweet error, try again later", Toast.LENGTH_SHORT).show();
                }
        }

        private void saveAccessToken(AccessToken at) {
                String token = at.getToken();
                String secret = at.getTokenSecret();
                Editor editor = mPrefs.edit();
                editor.putString(PREF_ACCESS_TOKEN, token);
                editor.putString(PREF_ACCESS_TOKEN_SECRET, secret);
                editor.commit();
        }
}

If you find this helpful please say thanks spacer Happy Coding

And any questions just ask!

The eclipse project src as promised:

—> TweetToTwitter <---

spacer

This entry was written by blundell, posted on February 1, 2012 at 8:13 pm, filed under Intermediate, Tutorial and tagged android, androidev, Intermediate, oauth, register, tweet, tweeting, twitter, twitter4j. Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL.

8 Comments

  1. spacer Mert
    Posted March 16, 2012 at 5:21 pm | Permalink | Reply

    Hello thanks for example. I downloaded your project and tried to run that. I changed only consumer key and secret. but it doesn not work. When i press login, toast appears and says “Twitter Login error, try again later” . What did I do wrong?

    • spacer blundell
      Posted March 17, 2012 at 9:07 am | Permalink | Reply

      Hi Mert,
      You’ll have to debug it, does the LogCat throw any exceptions? Did you have internet connection? Did you sign up to twitter correctly? Perhaps post a question on stackoverflow it has a nice Q&A design

  2. spacer Paul Bourke
    Posted March 8, 2012 at 1:36 pm | Permalink | Reply

    Hi blundell, does this code work for you when connected to a 3G/data connection? This and any other twitter4j examples I’ve tried only work on wifi for some reason :/

    • spacer blundell
      Posted March 8, 2012 at 7:01 pm | Permalink | Reply

      Yes it should do I can’t see why not. It must be a device issue, or maybe when you create your APK it’s getting pro-guarded and that is removing the twitter4j jar? (random guess).

  3. spacer Weeber
    Posted March 4, 2012 at 12:37 am | Permalink | Reply

    “Twitter Login error, try again later”

    The login is failing, I’m running the same code you posted, I just changed the CONSUMER_KEY and CONSUMER_SECRET to use my keys. The webview never shows up.

    • spacer blundell
      Posted March 4, 2012 at 10:46 pm | Permalink | Reply

      You may have missed some code, as it works for many others. Have you checked your manifest? What else does the LogCat say?

  4. spacer Kumar
    Posted February 21, 2012 at 4:58 pm | Permalink | Reply

    I would like to thank you for the sample code . It was really helpful. I created some addition methods to pass the mTwitter across the application but I am getting error in the setTwitter method. I have no idea why it is giving error. Please sujjest . I have pasted the code here pastebin.com/PKJcaSpJ

    • spacer blundell
      Posted February 22, 2012 at 8:11 am | Permalink | Reply

      What is the error your getting? If you could post your question on stackoverflow.com and link it here I can help with an answer.

Post a Comment

Click here to cancel reply.

Your email is never shared. Required fields are marked *

*
*
Related searches:
twitter intent blundell private import
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.