The article is part of Android Series that aims to discuss the fundamentals of developing applications on the Android Platform
Integrating social connectors such as Twitter, Facebook, Google+ etc. helps an Android develop personalise the user’s experience. Integrating social connectors also enables the user to recommend the usefulness of your app and in-turn helps promote your application through social advertisement. In this tutorial we build an application that integrates Twitter within your application.
|
Use case |
An Android application asks a user to authorise its use of the user’s Twitter identity. |
|
Difficulty |
Moderate to Advance |
|
Pre-requisites |
Android [Moderate] |
|
Tools |
Eclipse with Android Development Toolkit |
Following are steps we will undertake to understand and implement the use-case.
- Create a simple Android application that asks the user to authorise its use of the users Twitter identity and supported operations.
- Create and register a Twitter application on Twitter Developers
- Modify the Android application to handle the redirect from Twitter into the application.
Create a simple Android application that asks the user to authorise its use of the user’s Twitter identity and supported operations.
- Create an Android project with a simple layout.
-
Declare in the application manifest following permissions:
- The Android Manifest is otherwise very similar to most basic Android applications. Some parts in the following manifest will be explained later on in this tutorial.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.gnuc.android.tutorials.ouath.twitter" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".OAuthActivity" android:label="@string/app_name" android:theme="@android:style/Theme.Light.NoTitleBar" 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="gnuc-tutorials-oauth" android:host="twitter" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET" /> </manifest></web-app>
- Create an activity class ‘OAuthActivity’ where we setup an action to redirect user to Twitter authentication end-point to ask for permission to be granted to access user data. The class OAuthActivity looks like the following. We will enhance the functionality of this class after we have defined the web-service.
package com.gnuc.android.tutorials.ouath.twitter;
import java.io.BufferedInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.gnuc.android.framework.Logger;
import com.gnuc.android.framework.Tutorial;
import com.gnuc.android.framework.Tutorial.Pref;
public class OAuthActivity extends Activity
{
private static ProgressDialog pd = null;
//
String id = null, name = null;
Bitmap picture = null;
//
// Twitter
private static CommonsHttpOAuthConsumer twCONSUMER = null;
private static OAuthProvider twPRODUCER = null;
private final static String twKEY = "XXXXXXXXXXXXXXXXXXXXXX"; // Fill in your Twitter Consumer key
private final static String twSECRET = " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX "; // Fill in your Twitter Consumer secret
private final static String twCALLBK = " gnuc-tutorials-oauth://twitter";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//
Tutorial.cx = this;
//
Button tw = (ImageButton) findViewById(R.id.twitter);
tw.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
showProgressDialog("Contacting Twitter ...");
twCONSUMER = new CommonsHttpOAuthConsumer(twKEY, twSECRET);
twPRODUCER = new DefaultOAuthProvider("http://twitter.com/oauth/request_token", "http://twitter.com/oauth/access_token", "http://twitter.com/oauth/authorize");
twPRODUCER.setOAuth10a(true);
final String authUrl = twPRODUCER.retrieveRequestToken(twCONSUMER, twCALLBK);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
}
});
picture = BitmapFactory.decodeResource(Tutorial.cx.getResources(), R.drawable.twitter);
}
}
- The layout for the application is simply a Button, EditText’s and an ImageView. All views are used to display some information extracted using the social web service.
Create and register a Twitter application on Twitter Developers
- You will need an API key to access Twitter API. To do that you will first have to create an application and register it with Twitter. It’s simple!
- Go to Twitter Developers, log in, and create a new application.
- Most of the entries are straightforward. You will only need read-only access for basic operations.
-
Once you have created your application make note of the ‘Consumer key’ and ‘Consumer secret’. These are required to be updated in the class OAuthActivity.
Modify the Android application to handle the redirect from Twitter into the application.
- Once the user has authorised the application, Twitter will redirect the user to the specialised URI we have provided in the variable ‘twCALLBK’. The specialised URI looks like ‘gnuc-tutorials-oauth://twitter‘ and can be of your choice.
- The manifest file of your Android project is enhanced to capture URIs with URI scheme : android:scheme=”gnuc-tutorials-oauth“ and URI host : android:host=”twitter“ . Also note the new intent-filter added to the manifest for the application to be able to capture the URIs
- The class OAuthActivity is enhanced with the following methods to process the redirect from Twitter web-service and subsequently request authorisation against the Twitter end-point and finally request user’s information.
//---------------------------------------------------------------------------------------------------
// OAuthActivity.java
//---------------------------------------------------------------------------------------------------
@Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
Uri uri = intent.getData();
if (null != uri)
{
Message msg = new Message();
msg.what = 1;
msg.obj = uri;
OAUTH.sendMessage(msg);
}
}
@Override
public void onResume()
{
super.onResume();
try
{
if (null != pd && pd.isShowing())
pd.hide();
}
catch (Exception e)
{}
}
void twProcess()
{
Tutorial.background(new Runnable()
{
@Override
public void run()
{
try
{
//
final HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
final BasicHttpParams params = new BasicHttpParams();
final SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
final ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
//
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
DefaultHttpClient CLIENT = new DefaultHttpClient(cm, params);
//
HttpGet get = new HttpGet("http://api.twitter.com/1/account/verify_credentials.json");
get.setParams(params);
twCONSUMER.sign(get);
HttpResponse resp = CLIENT.execute(get);
//
showProgressDialog("Processing ...");
//
String respStr = EntityUtils.toString(resp.getEntity());
int respCode = resp.getStatusLine().getStatusCode();
if (respCode == HttpURLConnection.HTTP_OK)
{
JSONObject me = new JSONObject(respStr);
id = me.getString("screen_name");
name = "@"+me.getString("screen_name");
String profile = me.getString("profile_image_url");
try
{
URLConnection cxn = new URL(profile).openConnection();
cxn.connect();
picture = BitmapFactory.decodeStream(new BufferedInputStream(cxn.getInputStream(), 20));
}
catch (Exception e)
{
Logger.e(e);
}
OAUTH.sendEmptyMessage(3);
return;
}
else
OAUTH.sendEmptyMessage(-1);
}
catch (Exception e)
{
OAUTH.sendEmptyMessage(-1);
Logger.e(e);
}
}
});
}
public Handler OAUTH = new Handler()
{
@Override
public void handleMessage(Message msg)
{
try
{
OAUTH.removeMessages(msg.what);
switch (msg.what)
{
case -1 :
{
if (null != pd)
pd.cancel();
Toast.makeText(OAuthActivity.this, "Could not authenticate against Twitter. Please try another provider.", Toast.LENGTH_LONG).show();
break;
}
case 1 :
{
Uri uri = (Uri) msg.obj;
if (uri != null && uri.toString().contains(twCALLBK))
{
showProgressDialog("Reading response...");
String verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
if (null == twCONSUMER || null == twPRODUCER)
{
twCONSUMER = new CommonsHttpOAuthConsumer(twKEY, twSECRET);
twPRODUCER = new DefaultOAuthProvider("http://twitter.com/oauth/request_token", "http://twitter.com/oauth/access_token", "http://twitter.com/oauth/authorize");
twPRODUCER.setOAuth10a(true);
}
try
{
twPRODUCER.retrieveAccessToken(twCONSUMER, verifier);
Pref.OAUTH_TW_TOKEN = twCONSUMER.getToken();
Pref.OAUTH_TW_TOKEN_SECRET = twCONSUMER.getTokenSecret();
Pref.write();
showProgressDialog("Processing response..");
twProcess();
}
catch (Exception e)
{
OAUTH.sendEmptyMessage(0);
Logger.e(e);
}
}
break;
}
case 2 :
{
showProgressDialog((String) msg.obj);
break;
}
case 3 :
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
findViewById(R.id.gplus).setVisibility(View.GONE);
LinearLayout ll = (LinearLayout) findViewById(R.id.gplus_profile);
ll.setVisibility(View.VISIBLE);
ImageView ph = (ImageView) ll.findViewById(R.id.gplus_photo);
ph.setImageBitmap(picture);
//
EditText et = (EditText) findViewById(R.id.gplus_id);
et.setText(id);
et.setFocusable(false);
//
et = (EditText) findViewById(R.id.gplus_nickname);
et.setText(name);
et.setFocusable(false);
//
pd.cancel();
}
});
break;
}
}
}
catch (Exception e)
{}
}
};
void showProgressDialog(final String msg)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
try
{
if (null != pd)
pd.cancel();
}
catch (Exception e)
{}
pd = new ProgressDialog(Tutorial.cx);
pd.setMessage(msg);
if (!pd.isShowing())
pd.show();
}
});
}
//---------------------------------------------------------------------------------------------------
// Tutorial.java class is a utility class
//---------------------------------------------------------------------------------------------------
package com.gnuc.android.framework;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
public class Tutorial
{
public static final String TAG = "GNUC-TUTORIAL";
public static Context cx = null;
//
public static void background(final Runnable r)
{
new Thread()
{
@Override
public void run()
{
r.run();
}
}.start();
}
public static class Pref
{
public static String OAUTH_TW_TOKEN = "";
public static String OAUTH_TW_TOKEN_SECRET = "";
public static void read()
{
SharedPreferences p = cx.getSharedPreferences(TAG, Activity.MODE_PRIVATE);
OAUTH_TW_TOKEN = p.getString("OAUTH_TW_TOKEN", OAUTH_TW_TOKEN);
OAUTH_TW_TOKEN_SECRET = p.getString("OAUTH_TW_TOKEN_SECRET", OAUTH_TW_TOKEN_SECRET);
}
public static void write()
{
SharedPreferences.Editor pe = cx.getSharedPreferences(TAG, Activity.MODE_PRIVATE).edit();
pe.putString("OAUTH_TW_TOKEN", OAUTH_TW_TOKEN);
pe.putString("OAUTH_TW_TOKEN_SECRET", OAUTH_TW_TOKEN_SECRET);
//
pe.commit();
}
}
- To understand more about OAuth and the Twitter web-service please read the following resources: https://dev.twitter.com/docs/auth/oauth/faq and https://dev.twitter.com/docs/auth
In this tutorial we learnt how to create an Android application that integrates Twitter within your application.


The first step is to create a new AppEngine project in Eclipse.


















