Welcome!
Search the categories on the right for examples.
If you can't find what you need, then leave a comment on the Requests page!
Happy coding everyone.
New Add me on Twitter to get tweets on Think Android's latest posts!
Congrats to Packt Publishing! 1000 Titles and Counting!
Hey everyone,
Just got an email from Packt Publishing with the exciting news that they’ve published their 1000th title! Pretty impressive no?
Any ways, to celebrate:
————————————————————————————————————————————————————-
Dear Customer,
Packt Publishing has come a long way since it published its first book in 2004, and is now one of the leading technical publishers, renowned among developers for its focused and practical books on a wide range of tools and technologies.
Packt has just published its 1000th book. You are invited to join us in celebrating this milestone with a gift. Access our library, PacktLib, for free for a week, and choose any of our eBooks to download and keep.
To make use of this offer, you simply need to go to www.packtpub.com and log into your account, or register for an account, between the 28th and 30th September.
At Packt, we really appreciate your support in helping us get this far, and hope that you will continue to enjoy our range of books.
Kind regards,
Packt Publishing
————————————————————————————————————————————————————-
So yes – check out the resources they have and go get your free e-book! I’m definitely going to redeem mine =)
And PS, for those who don’t know, I happened to publish my book with Packt so if you’re interested feel free to download my e-book at Android Database Programming.
Happy coding as usual!
- jwei
Passing Objects in Intents: Parcelables and More
Hey everyone,
For this post, I thought I’d revisit the topic of Intents. In the past I’ve talked about passing Intents in between classes with simple, primitive data (see Passing Information between Activities) – turns out it’s a relatively easy task, and a core concept within the Android framework. However, the much harder task is passing your own classes (objects) in between Activities, and moreover, potentially passing lists of objects.
In this post, I’ll go through an example of writing an object that implements the Parcelable interface.
Consider a scenario where you have a list of Venues (i.e. Restaurants, Hotels, Clubs, anything with fields for lat, long, name, address, etc). Your user makes a request and gets back a list of these Venues. You then want to pass these results to a new Activity – maybe it’s a mapping Activity (as it was in my case), but regardless the goal is to pass this list of Venues from Activity A to Activity B without having to make the same request twice.
The first step is defining your object. The object must implement the Parcelable interface. Why you might ask? Well let’s step back and think about what’s happening here. Within Android, much of the inter-process (inter-Activity) communication is done through light weight data structures known as Parcels. In fact, both Intents and Bundles (two objects you’ve probably encountered before…) implement this Parcelable interface.
But how does this inter-process communication work? An Android process first converts an object into a byte stream which is then sent to another process (i.e. another Activity). This second process then reads in the byte stream and converts it back into an object: this exchange is more commonly known as serialization or marshalling. But how do the two Activities know what to do to serialize and de-serialize your object? For primitives like ints, doubles, even Strings, serialization is trivial as these primitives are already in byte form. And so this is where the Parcelable interface comes in.
By implementing the Parcelable interface, you are essentially giving the OS instructions on how to serialize and de-serialize your object. Conceptually this may be difficult to picture, but luckily Android has made the code for this super simply – in fact you are only required to override a few methods. With that, let’s take a look at what exactly needs to be done in the implementation:
public class ParcelableVenue implements Parcelable {
private double lat, lon;
private String name, address;
public ParcelableVenue(double lat, double lon, String name, String address) {
this.lat = lat;
this.lon = lon;
this.name = name;
this.address = address;
}
public ParcelableVenue(Parcel source) {
// TODO implement
}
public GeoPoint getGeoPoint() {
return new GeoPoint((int) (lat * 1e6), (int) (lon * 1e6));
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
@Override
public int describeContents() { // OVERRIDE METHOD #1
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) { // OVERRIDE METHOD #2
dest.writeDouble(this.lat);
dest.writeDouble(this.lon);
dest.writeString(this.name);
dest.writeString(this.address);
}
public static final Parcelable.Creator<ParcelableVenue> CREATOR = new Parcelable.Creator<ParcelableVenue>() {
// TODO implement
};
}
So far we have the basic structure of our ParcelableVenue object – it has a few simple fields as well as some standard getters; nothing special there. You’ll then notice that there are two methods we need to override. The first is the describeContents() method. Typically returning 0 suffices unless you have numerous parcelable objects and require special serialization for some. The method itself is meant to return a bit mask that identifies the serialized object. In my case, I just return 0.
The second method is the writeToParcel(Parcel dest, int flags) method. The meat of the conversion happens here. In this method you are passed a destination Parcel which is eventually serialized and sent to the end process. Thus you simply need to write your object’s data into this parcel. Luckily, some simple write methods are given to you, such as writeDouble(), writeString(), writeInt(), writeIntArray(), etc. The flags parameter simply tells the writeToParcel() method how the object should be written.
Once these two methods are overridden, every class that implements the Parcelable interface then needs to have a static Parcelable.Creator object named CREATOR. Let’s step back one more time – where are we at this point? Well so far we’ve flattened the object and written it to a Parcel object. Our object is in essence nothing but a byte stream now, so the only thing that’s left to do is un-flatten it and convert it back into an object using this CREATOR object!
Our creator object is pretty simple and need only look like:
public class ParcelableVenue implements Parcelable {
private double lat, lon;
private String name, address;
public ParcelableVenue(double lat, double lon, String name, String address) {
this.lat = lat;
this.lon = lon;
this.name = name;
this.address = address;
}
public ParcelableVenue(Parcel source) {
// TODO implement
}
// ...
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeDouble(this.lat);
dest.writeDouble(this.lon);
dest.writeString(this.name);
dest.writeString(this.address);
}
public static final Parcelable.Creator<ParcelableVenue> CREATOR = new Parcelable.Creator<ParcelableVenue>() {
@Override
public ParcelableVenue createFromParcel(Parcel source) {
return new ParcelableVenue(source); // RECREATE VENUE GIVEN SOURCE
}
@Override
public ParcelableVenue[] newArray(int size) {
return new ParcelableVenue[size]; // CREATING AN ARRAY OF VENUES
}
};
}
And so we see that the very last step is simply to write another constructor for our ParcelableVenue class which initializes an object given a Parcel. This can be done with:
public class ParcelableVenue implements Parcelable {
private double lat, lon;
private String name, address;
// ...
public ParcelableVenue(Parcel source) {
this.lat = source.readDouble();
this.lon = source.readDouble();
this.name = source.readString();
this.address = source.readString();
}
// ...
}
The order here is important – the first double read will be the first double written as, again, it is a byte stream.
And that’s it! Once we have our ParcelableVenue, we can then do things like:
public class ClubsListActivity extends ListActivity {
private List<Club> clubs;
private Button mapViewButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.club_list);
mapViewButton = (Button) findViewById(R.id.switch_map_view);
mapViewButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// PREPARE NEW INTENT TO SEND TO MAP ACTIVITY
Intent i = new Intent(ClubsListActivity.this, VenueMapView.class);
// INITIALIZE NEW ARRAYLIST AND POPULATE
ArrayList<ParcelableVenue> overlays = new ArrayList<ParcelableVenue>();
for (Club c : clubs) {
overlays.add(new ParcelableVenue(c.getLat(), c.getLon(), c.getName(), c.getAddress()));
}
// EMBED INTO INTENT
i.putParcelableArrayListExtra("venues", overlays);
startActivity(i);
}
});
SharedPreferences sp = getSharedPreferences(Constants.DB, Context.MODE_PRIVATE);
double lat = (double) sp.getFloat(Constants.SP_PREV_LAT, (float) Constants.DEFAULT_LAT);
double lon = (double) sp.getFloat(Constants.SP_PREV_LON, (float) Constants.DEFAULT_LON);
// GET CLUBS NEAR YOU WITH LAT LON
}
}
The receiving side then looks like:
public class VenueMapView extends MapActivity {
private MapView map;
private List<ParcelableVenue> venues;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.mapview);
SharedPreferences sp = getSharedPreferences(Constants.DB, Context.MODE_PRIVATE);
double lat = (double) sp.getFloat(Constants.SP_PREV_LAT, (float) Constants.DEFAULT_LAT);
double lon = (double) sp.getFloat(Constants.SP_PREV_LON, (float) Constants.DEFAULT_LON);
map = (MapView) findViewById(R.id.venue_map); // INIT MAP
map.setBuiltInZoomControls(true); // SET MAP CONFIGURATIONS
map.getController().setCenter(new GeoPoint((int) (lat * 1e6), (int) (lon * 1e6)));
int maxZoom = map.getMaxZoomLevel();
map.getController().setZoom(maxZoom - 3);
Intent i = getIntent(); // RETRIEVE OUR INTENT
venues = i.getParcelableArrayListExtra("venues"); // GET PARCELABLE VENUES
List<Overlay> mapOverlays = map.getOverlays();
Drawable icon = this.getResources().getDrawable(R.drawable.good_pin);
VenueOverlay vo = new VenueOverlay(icon, this); // INIT OVERLAY MARKERS
List<OverlayItem> points = new ArrayList<OverlayItem>();
for (ParcelableVenue v : venues) {
OverlayItem o = new OverlayItem(v.getGeoPoint(), v.getName(), v.getAddress());
points.add(o);
}
vo.addOverlayList(points);
// ADD VENUE OVERLAYS TO MAP
mapOverlays.add(vo);
}
}
I won’t say too much about what I’m doing with my Maps Activity – maybe I’ll save this for a future tutorial. The important thing to see is how I send a list of ParcelableVenue objects, and then retrieve them on the other side. As you can probably see by now, there’s nothing hard code wise when implementing a Parcelable object. The difficulty typically stems from an incomplete understanding of how Android sends data from process to process – and this is understandable as almost all of this is abstracted away so that we only need to put simple values into Bundles and Parcels and voila things magically appear on the other side. But once you dig a little more into what’s happening behind the scenes, then all of this serialization and Parcelable implementation makes much more sense.
And with that I send you off again! Happy coding and hope this helped.
- jwei
Parsing JSON on Android
Hey everyone,
Now a days when people talk about transferring data through HTTP requests, two popular data formats come to mind: JSON and XML.
In earlier posts, I’ve written a little about XML (see ), but in this post I’m going to use another friendly library to show you guys a simple, efficient way to parse JSON. I’ll also talk a little about the merits of each data format, but the hope is by the end of this short post, you’ll have what you need to parse both XML and JSON.
The “library” I’m going to take advantage of is the JSON-Java library. It’s a really nice, self-contained library, which allows you to easily parse JSON. More recently, the library has even included methods that allow you to convert XML to JSON and vice versa – allowing you to better reuse your data parsers. Anyways, before reading this post, go ahead and download the library and add the source to your project. For me, I just add a new package (i.e. jwei.apps.json) and put the files in there.
Once you have that, the rest is quite simple. Recently I worked on a project where I had to make an HTTP request to get a list of clubs in NY. Each Club was simply an object that contained fields like name, address, lat/long, phone number, etc. The JSON structure of the HTTP response looked like:
[ // note that square brackets declare a json array
{ // while curly brackets declare a json object
id: 11036,
zip: "",
lon: -73.9861709,
address: "240 W 47th St, New York, NY",
name: "The Supper Club",
number: "",
url: "",
lat: 40.7597637,
country: "United States"
},
{
id: 7034,
zip: "10019",
lon: -73.9863942,
address: "251 W. 48th St, New York, NY",
name: "XVI",
number: "",
url: "",
lat: 40.7607917,
country: "United States"
}
.
.
.
]
To see for yourself, feel free to hit this URL:
http://djs-corner.appspot.com/getClosestClubs?lat=40.7600624&lon=-73.98558
Then, subsequently my JSON club parser looked like:
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import jwei.apps.helpers.ConnectionManager;
import jwei.apps.json.JSONArray;
import jwei.apps.json.JSONObject;
import jwei.apps.types.Club;
import jwei.apps.types.Constants;
public class JsonParser {
private static DefaultHttpClient httpClient = ConnectionManager.getClient();
public static List<Club> getNearestClubs(double lat, double lon) {
// YOUR URL GOES HERE
String getUrl = Constants.BASE_URL + String.format("getClosestClubs?lat=%f&lon=%f", lat, lon);
List<Club> ret = new ArrayList<Club>();
HttpResponse response = null;
HttpGet getMethod = new HttpGet(getUrl);
try {
response = httpClient.execute(getMethod);
// CONVERT RESPONSE TO STRING
String result = EntityUtils.toString(response.getEntity());
// CONVERT RESPONSE STRING TO JSON ARRAY
JSONArray ja = new JSONArray(result);
// ITERATE THROUGH AND RETRIEVE CLUB FIELDS
int n = ja.length();
for (int i = 0; i < n; i++) {
// GET INDIVIDUAL JSON OBJECT FROM JSON ARRAY
JSONObject jo = ja.getJSONObject(i);
// RETRIEVE EACH JSON OBJECT'S FIELDS
long id = jo.getLong("id");
String name = jo.getString("name");
String address = jo.getString("address");
String country = jo.getString("country");
String zip = jo.getString("zip");
double clat = jo.getDouble("lat");
double clon = jo.getDouble("lon");
String url = jo.getString("url");
String number = jo.getString("number");
// CONVERT DATA FIELDS TO CLUB OBJECT
Club c = new Club(id, name, address, country, zip, clat, clon, url, number);
ret.add(c);
}
} catch (Exception e) {
e.printStackTrace();
}
// RETURN LIST OF CLUBS
return ret;
}
}
Again, it’s relatively straight forward, but the methods I’ll make special note of are:
JSONArray ja = new JSONArray(result);
JSONObject jo = ja.getJSONObject(i);
long id = jo.getLong("id");
String name = jo.getString("name");
double clat = jo.getDouble("lat");
In the first method, we pass in a String which has JSON format. The constructor of JSONArray expects a String that has valid JSON array formatting and parses it accordingly – throwing a JSONException otherwise. Once we have our JSON array, it works similarly to a vector (ArrayList) and we can pass it an index and retrieve a single JSONObject. For each JSONObject, we can then retrieve various fields by type (i.e. getLong, getDouble, getString, etc). Pretty simple no?
As mentioned before, to allow for better re-usability of data parsers, the writers of JSON-Java extended the library’s functionality to include XML conversion, which is simply:
String xml = ""; // YOUR XML STRING
JSONObject jo = XML.toJSONObject(xml);
String name = jo.getString("name");
...
Thus, if we wanted to ensure maximum compatibility, we could have extended our parser to look like:
public class JsonParser {
private static DefaultHttpClient httpClient = ConnectionManager.getClient();
public static List<Club> getNearestClubs(double lat, double lon, String format) {
// YOUR URL GOES HERE - OFTEN API REQUESTS WILL HAVE A FORMAT PARAM
String getUrl = Constants.BASE_URL + String.format("getClosestClubs?lat=%f&lon=%f&format=%s", lat, lon, format);
List<Club> ret = new ArrayList<Club>();
HttpResponse response = null;
HttpGet getMethod = new HttpGet(getUrl);
try {
response = httpClient.execute(getMethod);
// CONVERT RESPONSE TO STRING
String result = EntityUtils.toString(response.getEntity());
// CONVERT RESPONSE STRING TO JSON ARRAY
JSONArray ja;
if(format.equalsIgnoreCase("xml")) {
JSONObject xjo = XML.toJSONObject(result);
ja = xjo.getJSONArray("clubs");
} else if (format.equalsIgnoreCase("json")) {
ja = new JSONArray(result);
}
// ITERATE THROUGH AND RETRIEVE CLUB FIELDS
...
} catch (Exception e) {
e.printStackTrace();
}
// RETURN LIST OF CLUBS
return ret;
}
}
And voila!
Now, as for a brief discussion on JSON vs. XML, I’ll note three points:
1) Performance – in terms of performance, JSON is the better option. This is true for both the actual transferring of your data, and also for the parsing of the data. This is due to the lower overhead needed for JSON formatting, which doesn’t require the rigid tree/node structure of XML.
2) Readability – this is a more subjective point and I’ve seen arguments for both sides. I personally think XML is the cleaner format for reading, but most browsers now a days (i.e. Chrome, Firefox) have JSON and XML display built in and both are nicely laid out. However, I will mention that for more “complex” data structures, XML tends to display it in a more intuitive fashion, which leads me to my third point.
3) Complexity – while JSON is designed for quick and lean data structures, XML is built to handle data structures of varying complexity and depth. Consider a data structure that has fields which are several layers deep (i.e. a University object which has a list of Class objects which each have a list of Student objects which each have a list of …). When this is the case, it can quickly become a parsing headache when you’re wading through JSONArray after JSONArray trying to access the correct JSONObject. Here, having an XML parser, especially one that is equipped with tree traversing languages like XPATH, can be an extremely powerful tool for pinpointing the precise nodes you want.
And so I’ll end the post with that. Hope this was comprehensive and helpful!
As always – happy coding.
- jwei
Granting Content Provider URI Permissions
Hey everyone,
The goal of this short example is to show you how you can further protect your application’s data by enforcing permissions upon your custom content provider. For those who have never seen a custom content provider implementation, I invite you to check out my post Writing Your own Content Provider before reading on.
The purpose of giving your content provider the ability to grant access to its data should be pretty clear. Suppose you want to protect the integrity of your content provider’s data. Then, for some users/applications you may want to give them both read and write permissions, while for others you may only want to give them read permission. A simple example of this is attachments in a mail application [taken from Google]:
Access to the mail should be protected by permissions, since this is sensitive user data. However, if a URI to an image attachment is given to an image viewer, that image viewer will not have permission to open the attachment since it has no reason to hold a permission to access all e-mail.
These permissions are for a specific content URI, and will last until the Activity that receives them is finished. In other words, when an application grants read and/or write permissions to another Activity, these permissions are temporary. Before moving on to some code, let me note that this implementation is different than declaring the android:readPermission and android:writePermission attributes as these tags specify specific applications and give those applications permanent read/write access. In this way, the method below which uses the android:grantUriPermissions tag a.k.a the sub-tag grant-uri-permission is much more dynamic and flexible.
So let’s see how all this is done. Adding permission requirements to your content provider is actually quite simple. Let’s extend my Notes ContentProvider from the above example and give it the ability to grant URI permissions. Say you want to give the user the ability to share his/her notes through various mail/social-media applications, but you want to protect the content of the note. Then, you’ll want to add the following to your AndroidManifest.xml file:
<provider android:name="jason.wei.apps.notes.providers.NotesContentProvider"
android:authorities="jason.wei.apps.notes.providers.NotesContentProvider"
android:grantUriPermission="true" <!-- for granting URI-based permissions throughout the entire provider -->
<grant-uri-permission android:pathPattern="/notes/" /> <!-- for granting URI-based permissions to specific sub-branches of the provider -->
</provider>
What I mean by the distinction “permissions throughout the entire provider” versus “permissions to specific sub-branches of the provider” is that in the former, any URI with pattern:
“jason.wei.apps.notes.providers.NotesContentProvider/…”
Will have the ability to grant permissions, while in the second only URIs with pattern:
“jason.wei.apps.notes.providers.NotesContentProvider/notes/{id}”
can grant URI permissions (for those struggling with the concept of URIs, just think of this as giving your entire hard drive some desired property, versus only giving one directory in your hard drive that same property). Finally, as for how you actually go about granting such permissions through Intents, the below shows it done in a generic Activity:
public class NoteUriGrantActivity extends Activity {
public static final String NOTE_ACTION_VIEW = "jason.wei.custom.intent.action.NOTE_VIEW";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... code ...
// IMPLICIT INTENT EXAMPLE
Uri uri = Uri.parse("content://jason.wei.apps.notes.providers.NotesContentProvider/notes/1");
Intent intent = new Intent();
intent.setAction(NOTE_ACTION_VIEW); // SET CUSTOM INTENT ACTION
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // GRANT TEMPORARY READ PERMISSION
intent.setData(uri);
startActivity(intent); // SEND INTENT TO BE RESOLVED
// EXPLICIT INTENT EXAMPLE
grantUriPermission("jason.wei.apps.NotesReader", uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
And with that, in order to resolve our custom Intent, we simply need to write a separate Activity (note this Activity need not be defined within the same application as the ContentProvider) with correctly specified intent filter:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jason.wei.apps.NotesReader"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".NoteReaderActivity" android:label="@string/app_name" >
<intent-filter>
<action android:name="jason.wei.custom.intent.action.NOTE_VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
And voila! Now your NoteReaderActivity simply needs to call the getIntent() method to retrieve the content of the note! Architecturally, this process looks like:
And once the NoteReaderActivity obtains the content of the note, it has the ability to layer on top any additional functionality (i.e. including pictures, videos, other media content) before ultimately sharing it with your friends.
Here, at the end of the day, everyone is happy. The NotePad application can allow other applications on the device to consume its content without fear of data corruption, while the NoteReader application can focus on non-content related issues such as UI, media attachments, group sharing, etc.
Hope this helps and happy coding!
- jwei
Book: Android Database Programming
Hey everyone!
First off – I just wanted to thank you all for making this blog what it is. It’s been great getting your feedback through comments and emails, and I hope this blog has helped you guys in your development ambitions as much as it has helped me!
I’m pleased to announce the publication of my first book, Android Database Programming. It was actually through this blog that publishing company Packt contacted me and asked me to write on the topic.
As for what the book covers, I’ll briefly summarize here:
- Learn about lighter forms of local data storage such as SharedPreferences
- Dive into SQLite databases and learn how to customize and extend them
- Examine various SQLite queries to efficiently query for your data
- Learn to safely expose your SQLite database to external applications
- Understand how to bind your SQLite database to the user interface
- Explore various external databases such as Google App Engine and learn how to store/query data on these external platforms
- Learn to make network requests to both post and get data from your external data store
- Learn to retrieve, parse, and/or cache the incoming web data on the Android application
It’s currently available for purchase in both print and eBook/Kindle, and can be purchased through the publisher’s website as well as through Amazon.
A sample copy of Chapter 2 is also available for free.

Hope you guys like it and thanks again for all the support. As always, happy coding.
- jwei
2011 In Review
The WordPress.com stats helper monkeys prepared a 2011 annual report for this blog.
Here’s an excerpt:
London Olympic Stadium holds 80,000 people. This blog was viewed about 530,000 times in 2011. If it were competing at London Olympic Stadium, it would take about 7 sold-out events for that many people to see it.


