iPhone Development: 12 Tips To Get You Started

January 4th, 2012

iPhone Development: 12 Tips To Get You Started

If you were a good developer all through the past year, perhaps Santa brought you a shiny new iPhone. If he did, you’ve certainly spent hours playing with it – browsing, downloading apps, microblogging, and all in all having lots of fun.

Now, being the web developer that you are, you’re probably wondering where the heck is “View Source,” and how you can create sites and apps that look and work great on the iPhone. Here are some tips and tricks to start you off – and best of all, you can practice on a simulator if you’ve yet to make the big purchase.

1: Documentation and the iPhone Simulator

“Documentation: none,” proclaimed Peter-Paul Koch when he started playing with Safari for iPhone – but the situation has changed since then. Apple now makes iPhone-specific web development information available as part of the Safari documentation.

The iPhone SDK (software development kit), which is Mac-only, also contains an iPhone simulator – this is very handy if you already own an iPhone, and of course it’s absolutely essential if you’re yet to join the iPhone army. To access it, you’ll need to register as an iPhone developer, and install the iPhone SDK. Once you’ve installed it, you’ll find the iPhone simulator in /Developer/Platforms/iPhoneSimulator.platform/Developer/Applications.

2: Small Screen CSS

The most obvious difference between an iPhone and your PC or Mac is that the iPhone has a much smaller screen. If you already have a page that works in desktop browsers and screen readers, one simple strategy is to have an additional style sheet that’s only used by the iPhone. Here’s the markup you’d use:

  1. <!–[if !IE]>–> <br>
  2. <link  <br>
  3. rel=”stylesheet”  <br>
  4. href=”small-screen.css”  <br>
  5. type=”text/css”  <br>
  6. media=”only screen and (max-device-width: 480px)”  <br>
  7. /> <br>
  8. <!–<![endif]–>

This link element uses a media query to target devices with a maximum width of 480 pixels – that is, the available width when the iPhone is in landscape orientation. The IE conditional comments are needed for IE version 5.5 or earlier; these versions lack support for the media query and will load the style sheet intended for the iPhone. Let’s try an example.

In Example 1, we can see a page that will display a red box to iPhone viewers, and a blue one to other viewers. A style sheet, common.css, contains styles intended for all browsers, including the declaration for the blue box. Another, small-screen.css, is intended for handheld devices and contains the declarations for the red box. When you load this example in an iPhone, you’ll see the red box; on your desktop, you’ll see blue.

If you’d prefer to use only one style sheet, you could add the iPhone-only styles to the main style sheet using an @media block, like so:

  1. @media only screen and (max-device-width: 480px) { <br>
  2. #test-block { <br>
  3. background: red; <br>
  4. } <br>
  5. }

We can see an example of an inline stylesheet in use in Example 2. In the stylesheet it uses, onestyleforall.css, you’ll see the declaration for a red background in an @media block.

3: The Viewport Meta Element

By default, Safari on the iPhone will render your page as if it was a desktop browser on a big screen, with 980 pixels width available for the web content. Then it will scale down the content so that it fits the small screen. As a result, the user sees your page with miniscule, illegible letters and must zoom in to see the interesting parts. This might be okay for your web pages, but if you’re designing a web app that aims to look like a native application, this is unacceptable.

Luckily, this is easy to correct using the special viewport meta element:

  1. <meta name=”viewport” content=”width=device-width” />

This element instructs the browser to use the width of the device as the width of the viewport, instead of the default 980 pixels. We can see the difference with two examples.

  1. Example 3 shows a simple paragraph element and no viewport meta element. The font is almost unreadable.
  2. Example 4 includes the viewport element. Now that the device width is only 320 pixels, the font size is much easier to see.

Alternatively, you can set a device-width value to any number you like. For example, let’s say your blog has a layout with a fixed width of 750 pixels, so that it fits nicely in an 800×600 desktop screen. Example 5 shows a stripped-down version of this kind of layout: if you load it in the iPhone, you’ll see white space that fills up the rest of the 980 pixels.

To eliminate the extra space, you can use the viewport meta element and set the width to 780px:

  1. <meta name=”viewport” content=”width=780″ />

Example 6 shows a version of our fixed layout with this viewport meta element.

The content of the meta viewport element can also contain multiple comma-delimited values, such as initial-scale – the zoom level at which the user initially sees your page – as well as whether the interface is user-scalable. For web apps, a common set of values is:

  1. <meta name=”viewport” content=”width=device-width,initial-scale=1,user-scalable=no” />

This element sets the width to the maximum device width (as we saw before), zooms into a zoom level of one, and also forbids the user to zoom in and out of the content. That’s handy for web apps that should look and feel like a native application.

6 Tools for Testing Mobile Web Designs

January 4th, 2012

6 Tools for Testing Mobile Web Designs

One of the most important processes when designing for the web is testing. We’re all aware that one of the challenges of web design is ensuring the site looks good in multiple browsers. As the mobile web becomes more and more important, you need to know how your site or widget looks on a mobile device. But there are so many devices, how do we test them all?

One of the most important processes when designing for the web is testing. We’re all aware that one of the challenges of web design is ensuring the site looks good in multiple browsers. As the mobile web becomes more and more important, you’ll also want to know how your existing site or widget looks on a mobile device, but there are so many devices, how do we test them all?

As the number of people using mobile devices increases, so too does the pressure to ensure that our websites look good and are legible on a mobile device. The ideal, and unrealistic situation, would be to test on real handsets, but obviously this would be impossible for most designers. Fortunately, there are number of tools available online, allowing you to put your site through its mobile paces.

Device Anywhere is a commercial operation, allowing customers to sign up and test “Any Device. Any Network. Anywhere.” There are a range of subscription plans but you can sign up for a free trial.

MobiReady is tests mobile-readiness using industry best practices and standards. After testing you receive a free report outlining how well your site performs.

Opera Mini is a live demo of the Opera Mini browser that functions like it would when installed on a handset.

W3C Mobile OK Checker performs a range of tests on a web page to determine its level of mobile-friendliness. The short report produced will tell you where you’re going wrong.

dotMobi Emulator emulates a real mobile phone web browser. It’s a bit limited as you can only choose from two different phones you like as a skin.

iPhoney, as you could imagine, is specific to iPhone testing. It’s a downloadable application that is precise to the pixel, so useful for the designer working on iPhone apps.

There are other simulators and emulators available, particularly if you’re willing to pay, but this set will give you a fairly easy method of testing designs for free. Have you used these or any other tools to check your designs?

Going Undercover on Android Apps

January 4th, 2012

Going Undercover on Android Apps

In this article we go undercover on the approach to developing Android apps. As a professional programmer, with some iOS experience, Bruce Cooper can offer a qualified viewpoint on the experience. His report touches on user interface guidelines, the tools available to craft them, publishing in the Android Market place, platform fragmentation, in app advertising, open source and the future.

Profiling Android

About a year ago, a new generation of Android phones became available, and the buzz was that Android could now compete with iOS for features and desirability. I had already done some iPhone coding, plus I was in the market for a new phone, so I thought it would be a good opportunity to learn a new technology and hopefully produce something useful while I was at it.

Quick & Painless

When I was deciding what sort of app to write, I wanted it to be something simple, for a couple of reasons. Firstly, I wanted to learn the API and not over-tax myself. Secondly, by making it simple, I’d be more likely to finish up quickly and get it out to the public.

Publishing my app was important as I wanted to compare the experience of developing on Android to that of iOS. We’ve all heard the stories about having to deal with Apple’s mysterious approval process, and Google’s was supposed to be much easier. So off I went to the local phone store and I came back with a shiny new Samsung Galaxy S i9000.

One other thing I wanted to try out was mobile advertising. Again, we’ve all heard about people being able to make more money through in app advertising than through revenue from store sales. I didn’t expect much, but the only way to understand something is to do it. For advertising, I chose AdMob, as it appeared to be the preeminent platform at the time.

Taking Aim

I wanted to write something that would be useful for my target audience: me. I settled on writing a usage checking application, that would show the bandwidth usage of my phone (Optus) and my home ISP (Internode) to ensure that I didn’t go over my quotas. It would be called NodeDroid. Most of the existing usage checking apps for Android are either very basic or only work for one provider, and its information that I look up all the time. More information can be found about NodeDroid at 8bitcloud

After reading up on the technical details of how to program for Android, I started thinking about how the application should flow, and this is where I noticed the first differences between iOS and Android. Apple has gone to great lengths to specify the way that you will interact with iOS and the UI guidelines. The graphical interface builder goes a long way towards helping developers produce layouts that look like Apple UIs.

Whilst Android also has UI guidelines, they are less rigorously enforced. The GUI builder built into Eclipse for Android is terrible, meaning most people will end up building their interfaces by hand in XML rather than using a GUI builder, which often leads to ugly interfaces (As an aside, I think that programmatically built layouts can often work better than GUI built ones, but you need to put more effort in to get them right).

Other people have noted that the Android experience isn’t as consistent as iOS, and in my opinion this is one of the reasons why. I still wanted a good experience though, so a lot of effort was spent on making swipe gestures work correctly, including animation between states. I was a bit disappointed that it didn’t work out of the box. Some of this required specialised coding, which I will cover in another post.

Anatomy of a Mobile App

It is important to keep apps simple. Whilst it is tempting to put a whole bunch of stuff into an app, for mobile devices the limitations of screen real estate and input mechanisms mean that often, less is more. I didn’t want lots of buttons on my app; buttons, in general are a no-no on mobile apps, with gestures being a better way to interact.

Colour is also an important tool that allows you to differentiate between different components. NodeDroid supports accounts from multiple suppliers, with each provider displayed on a separate page. Colouring the pages with the colours of each provider means they become instantly identifiable by brand. Internode accounts ended up an orangey red, whilst Optus came out yellow. I’m no graphic artist, so the result was only partially successful, but I’m happy with the user experience that the colours provide. The effect would be even stronger with logos.

The last aspect of user experience I wanted to get right was how to show the results. The most easy to read format for info is graphs. I went looking for available plotting libraries, and found a few, but they were over complicated or too immature. In the end, as the graphs I was writing were very simple, I wrote my own components to draw the graphs.

Bringing it Together

So how did it end up? The first version of the application was quick to develop. This was aided by the use of Java as the programming language because I am a professional Java programmer, and switching to the Android APIs was easier than learning Objective-C for iOS. Working with Eclipse as a tool, in my opinion, is much easier than the awful XCode. Also, most Java APIs work very well on Android, meaning there’s lots out there already.

Publishing to the Android market was a breeze. After a one time US$25 registration fee (cheaper than Apple’s US$99 per year), I could publish my App immediately, through a straight forward web interface. This was especially useful when I found a bug in the first release, and needed to republish immediately to fix it. If I were dealing with Apple, there could have been a whole palaver about getting the new version out, but on Android it was simply a matter of uploading the new app bundle, and pressing Publish again. The market developer console also has a bunch of handy reporting tools which give you great feedback on downloads, issues, and comments.

Advertising was a mixed bag. Whilst installing and using adverts was easy, and I had a reasonable click through rate when adverts were available, often the service would be unable to provide adverts when requested leading to a poor number of ads shown (known as the fill rate). When this happened, it pretty much stopped the revenue dead. In the end, I made about $20 from advertising before I ended the experiment after two months. This sounds terrible, but remember this is a little app with only a few thousand users. It’s not going to pay the bills, but I can see why people like it as an approach: if you have a popular application with tens of thousands of users, advertising revenue could start to stack up.

Challenges

One challenge that I thought was inevitable would be the sheer variety of different screen sizes and versions of Android that are out there, otherwise known as “fragmentation”. People have been making a big fuss over this, but I can’t say I’ve really had a problem. The Google tools allow you to target a specific version, and as long as you are willing to do without the latest APIs, you can target fairly old devices easily. I had to make a few adjustments, but it was easy to target all Android 1.6+ devices.

Screen resolution was a bit more tricky. You tend to write your application for one screen resolution, then see how well it works in others. Luckily Google has provided pretty good tools to make your UI scale well, and if you write your application correctly it should work smoothly. I won’t say that my application works perfectly on every screen, but it works well on the vast majority. In the end, fragmentation really hasn’t been that much of a problem for me.

The Future

There are a lot of improvements I could make to my little application. I want to add a home screen widget to it, plus it would be great to add additional network providers to it. I’m still trying to work out how to do this in a secure fashion so that collaborators don’t have to share passwords with me. Its hard to debug without an account to work with.

As a first step, I have open sourced the application, it is available at my GitHub NodeDroid repository. If you just want to try the application, you can get it from the Android Market.

Twitter, Meet Android

January 4th, 2012

Twitter, Meet Android

You’ve said Hello Android. You’ve written your first app. You want to write something “real world” now. Daniel Bradby is back to develop a Twitter feed. This tutorial covers data lists, customization, accessing remote services, parsing data, and responsive interfaces. You should have a complete, functioning set of example code at the end.

In my recent article Hello Android, we created our first Android app featuring a basic Hello World function. Well, it seems the real Hello World of the mobile world is a Twitter feed.

This tutorial will guide you through creating a simple Android app to display a list of tweets coming from the JSON based search API provided by Twitter. We will work through the following points:

  • Displaying a list of items
  • Customizing the look of each list item
  • Accessing remote services and parsing data
  • Creating responsive user interfaces

For instructions on how to set up an Android development environment, take a look at the previous article Hello Android, which guides you all the way from installing software and establishing a workspace through to running a skeleton app in the Android Emulator.

Displaying Lists

To get started on our new project, create a new Android project in Eclipse (File -> New -> Other -> Android and select Android Project), entering an appropriate project name, application name, package name, and a name for the single launch activity.

You can see the options I’ve used below:

To check that you have created the project correctly, run the skeleton app in the emulator by highlighting the project name in Eclipse and selecting Run -> Run As -> Android Application.

Currently the Activity you have created will be extending android.app.Activity, and in your onCreate method you will be setting the ContentView of the activity to R.layout.main (linking to the layout as specified in /res/layout/main.xml). The Android SDK provides a convenient way to quickly display a list of data using a superclass called android.app.ListActivity. This Activity already provides a ContentView, configured with a ListView, ready to use and populate with data.

Now change the superclass of TwitterFeedActivity to extend ListActivity, removing the setting of the ContentView from the onCreate method.

The ListView now needs to be given data to display, along with a means to map that data into rows. ListAdaptors provide this mechanism and are set on the underlying ListView of the ListActivity using setListAdaptor.

Create some sample data containing two Strings, and an Android SDK provided adaptor (ArrayAdaptor) that knows how to handle arrays of arbitrary data into ListViews (The Android SDK also comes with several other ListAdaptors, such as Cursor Adaptors, which can assist when connecting local data storage to a ListView). You also need to provide the adaptor with a layout it can use to render the elements onto each row. In the example below we are using the Android SDK provided layout, simple_list_item_1, which is a single text label–perfect for laying our single strings:

1 public class TwitterFeedActivity extends ListActivity {
2 @Override
3 public void onCreate(Bundle savedInstanceState) {
4 super.onCreate(savedInstanceState);
5 String[] elements = {"Line 1", "Line 2"};
6 setListAdapter(new ArrayAdapter&lt;String&gt;(this, android.R.layout.simple_list_item_1, elements));
7 }
8 }

Adjust your code as above and confirm the following results in the emulator:

Customizing List Items

The basic Twitter client needs to display at least two fields per row: the author of the tweet, and the content of the tweet. In order to achieve this you will have to move beyond the inbuilt layout and ArrayAdaptor and implement your own instead.

Start by creating a class called Tweet that can be used to hold both the author and the content as Strings. Then create and populate a Tweet object with some test data to be displayed in the custom list item:

1 package com.sitepoint.mytwitter;
2 public class Tweet {
3 String author;
4 String content;
5 }

Create a layout XML file in /res/layout/list_item.xml to define two TextViews to display the content and author on separate rows. In order to display them one above the other, use a LinearLayout, configured to render each element within it vertically (android:orientation="vertical").

01 &lt;?xml version="1.0" encoding="utf-8"?&gt;
02 &lt;LinearLayout xmlns:android="<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>"
03 android:orientation="vertical"
04 android:layout_width="fill_parent"
05 android:layout_height="?android:attr/listPreferredItemHeight"
06 android:padding="6dip"&gt;
07 &lt;TextView android:id="@+id/toptext" android:layout_width="fill_parent"
08 android:layout_height="wrap_content"
09 android:gravity="center_vertical" android:singleLine="true" /&gt;
10 &lt;TextView android:layout_width="fill_parent"
11 android:layout_height="wrap_content" android:id="@+id/bottomtext"
12 android:singleLine="true" /&gt;
13 &lt;/LinearLayout&gt;

Once the XML file has been created, the Android Eclipse plugin will automatically add it as a reference into the generated R file. This R file is kept under the /gen folder of your project and acts as a bridge between your XML elements and your Java code. It allows your Java code to reference XML elements and files created under the /res folders. The file you have just created can now be referenced as R.layout.list_item in the Java code, as you will do next in the custom list adaptor.

Create a private class (inside the Activity) called TweetListAdaptor which subclasses ArrayAdaptor. This class should be used to store an ArrayList of the Tweets being displayed, as well as providing a way to map the Tweet objects to the TextViews you created in the layout above.

This mapping overrides the getView method in ListAdaptor, and should return a View object populated with the contents of the data at the requested position:

1 public View getView(int position, View convertView, ViewGroup parent) {

Furthermore, it should–if possible–reuse any View objects being passed into the method through the convertView parameter. If a new View object has to be created for every element in a list, large lists would stutter when they scroll. Caching Views allows the minimum amount of View objects to be created to populate a large list of data.

The complete implementation of the custom TweetListAdaptor is below. Note the “if statement” checking whether the passed convertView is able to be reused. If the View is null, the ListView has run out of Views to display and requires a new View to be created for this row.

This is achieved using the LayoutService, which is able to inflate (or load) the layout as you specified earlier in XML. You will see here how to reference the layout file using the generated R class through the R.layout.list_item reference.

Once a View is created (or reused), the particular Tweet is extracted from the ArrayList at the position required to be rendered by the ListView. You are then able to obtain references to the two TextView elements using the ids assigned to them in the XML (for example, android:id="@+id/toptext"). Once you have the references, you can set them with the appropriate content and author from the Tweet object.

01 private class TweetListAdaptor extends ArrayAdapter&lt;Tweet&gt; {
02 private ArrayList&lt;Tweet&gt; tweets;
03 public TweetListAdaptor(Context context,
04 int textViewResourceId,
05 ArrayList&lt;Tweet&gt; items) {
06 super(context, textViewResourceId, items);
07 this.tweets = items;
08 }
09 @Override
10 public View getView(int position, View convertView, ViewGroup parent) {
11 View v = convertView;
12 if (v == null) {
13 LayoutInflater vi = (LayoutInflater) getSystemService
14 (Context.LAYOUT_INFLATER_SERVICE);
15 v = vi.inflate(R.layout.list_item, null);
16 }
17 Tweet o = tweets.get(position);
18 TextView tt = (TextView) v.findViewById(R.id.toptext);
19 TextView bt = (TextView) v.findViewById(R.id.bottomtext);
20 tt.setText(o.content);
21 bt.setText(o.author);
22 return v;
23 }
24 }

Now the onCreate method can be adjusted to use the custom list adaptor with the created test data as shown below:

01 public void onCreate(Bundle savedInstanceState) {
02 super.onCreate(savedInstanceState);
03 Tweet tweet = new Tweet();
04 tweet.author = "dbradby";
05 tweet.content = "Android in space";
06 ArrayList&lt;Tweet&gt; items = new ArrayList&lt;Tweet&gt;();
07 items.add(tweet);
08 TweetListAdaptor adaptor = new TweetListAdaptor(this,R.layout.list_item, items);
09 setListAdapter(adaptor);
10 }

which will display the following, when run in the emulator:

Accessing Remote Services and Parsing Data

The Android SDK contains packages aimed at simplifying access to HTTP-based APIs. The Apache HTTP classes have been included and can be found under the org.apache.http package. You’ll be using these classes, along with the org.json classes to parse the data coming back from a call out the to Twitter search API.

Before any remote services can be accessed from an Android app, a permission has to be declared. This will alert the user (of your app) of what the app might be doing. Permissions could be to monitor incoming SMS, read the address book or, in your case, to simply make a request on the internet. These permissions are displayed to a user in the Android Market place before an app is installed, giving the user the choice of whether they want to give this app the declared permissions.

The permission you need to use is INTERNET and should be inserted outside of the application tag in the AndroidManifest.xml file.

1 &lt;/application&gt;
2 &lt;uses-permission android:name="android.permission.INTERNET" /&gt;
3 &lt;/manifest&gt;

With the permission in place, we can create a private method in the Activity that makes a request, parses the result, and returns an ArrayList of Tweet objects. The code listed below makes the request and looks for the resulting JSON array, which is iterated to extract each tweet’s text and from_user elements.

01 private ArrayList&lt;Tweet&gt; loadTweets(){
02 ArrayList&lt;Tweet&gt; tweets = new ArrayList&lt;Tweet&gt;();
03 try {
04 HttpClient hc = new DefaultHttpClient();
05 HttpGet get = new
06 HttpGet("<a href="http://search.twitter.com/search.json?q=android">http://search.twitter.com/search.json?q=android</a>");
07 HttpResponse rp = hc.execute(get);
08 if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
09 {
10 String result = EntityUtils.toString(rp.getEntity());
11 JSONObject root = new JSONObject(result);
12 JSONArray sessions = root.getJSONArray("results");
13 for (int i = 0; i &lt; sessions.length(); i++) {
14 JSONObject session = sessions.getJSONObject(i);
15 Tweet tweet = new Tweet();
16 tweet.content = session.getString("text");
17 tweet.author = session.getString("from_user");
18 tweets.add(tweet);
19 }
20 }
21 } catch (Exception e) {
22 Log.e("TwitterFeedActivity", "Error loading JSON", e);
23 }
24 return tweets;
25 }

Now replace the dummy data you previously used with a call to the loadTweets method when constructing the custom list adaptor in the onCreate method.

1 TweetListAdaptor adaptor = new TweetListAdaptor(this,R.layout.list_item, loadTweets());

Run this in the emulator and you should now see real data coming back from the API request being displayed in the list view as below:

Creating Responsive User Interfaces

The code in its current state has the potential to cause an Application Not Responding (ANR) dialog to appear, prompting the user to quit your app. This can occur due to the long-running work of making a remote request for data being performed within methods such as onCreate.

Long-running tasks should never be performed on the main application thread (which drives the user interface event loop). They should instead be spawned off into child threads to perform the work.

While Java’s Thread class can be used for this task, there is a complication in that once the long-running task is complete, it generally wants to change the user interface to report the results (that is, display a list of tweets loaded from a request).

User interface elements can only have their state altered from the main thread, as the Android UI toolkit is not thread-safe, therefore the background thread needs to message back to the main thread in order to manipulate the UI.

Thankfully, the Android SDK provides a convenient class AsyncTask, which provides an easy mechanism for asynchronous tasks to interact safely with the UI thread. This is achieved by subclassing AsyncTask and overriding the doInBackground method to perform the long-running task, then overriding onPostExecute to perform any manipulations on the UI.

When the AsyncTask is created (it has to be created on the UI thread) and executed, the doInBackground method is invoked on a background thread. On completion, the onPostExecute method is invoked back on the main UI thread.

To use this in your app, you will need to implement a private class within the Activity (like the custom adaptor class) called MyTask, which subclasses AsyncTask. You can override the doInBackground method with the contents of your previous loadTweets method.

Instead of the ArrayList being returned, you maintain an instance variable in the Activity so that the data can be shared across the private classes. Then in the onPostExecute you can set the List Adaptor with the data, as was done previously in onCreate. The onCreate method now simply creates the MyTask object and calls the execute method.

In order to demonstrate the UI responding while the background request is being performed, I have added a ProgressDialog to the AsyncTask as well. The complete listing of the Activity is below:

01 package com.sitepoint.mytwitter;
02 import java.util.ArrayList;
03 import org.apache.http.HttpResponse;
04 import org.apache.http.HttpStatus;
05 import org.apache.http.client.HttpClient;
06 import org.apache.http.client.methods.HttpGet;
07 import org.apache.http.impl.client.DefaultHttpClient;
08 import org.apache.http.util.EntityUtils;
09 import org.json.JSONArray;
10 import org.json.JSONObject;
11 import android.app.ListActivity;
12 import android.app.ProgressDialog;
13 import android.content.Context;
14 import android.os.AsyncTask;
15 import android.os.Bundle;
16 import android.util.Log;
17 import android.view.LayoutInflater;
18 import android.view.View;
19 import android.view.ViewGroup;
20 import android.widget.ArrayAdapter;
21 import android.widget.TextView;
22 public class TwitterFeedActivity extends ListActivity {
23 private ArrayList&lt;Tweet&gt; tweets = new ArrayList&lt;Tweet&gt;();
24 @Override
25 public void onCreate(Bundle savedInstanceState) {
26 super.onCreate(savedInstanceState);
27 new MyTask().execute();
28 }
29 private class MyTask extends AsyncTask&lt;Void, Void, Void&gt; {
30 private ProgressDialog progressDialog;
31 protected void onPreExecute() {
32 progressDialog = ProgressDialog.show(TwitterFeedActivity.this,
33 "", "Loading. Please wait...", true);
34 }
35 @Override
36 protected Void doInBackground(Void... arg0) {
37 try {
38 HttpClient hc = new DefaultHttpClient();
39 HttpGet get = new
40 HttpGet("<a href="http://search.twitter.com/search.json?q=android">http://search.twitter.com/search.json?q=android</a>");
41 HttpResponse rp = hc.execute(get);
42 if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
43 {
44 String result = EntityUtils.toString(rp.getEntity());
45 JSONObject root = new JSONObject(result);
46 JSONArray sessions = root.getJSONArray("results");
47 for (int i = 0; i &lt; sessions.length(); i++) {
48 JSONObject session = sessions.getJSONObject(i);
49 Tweet tweet = new Tweet();
50 tweet.content = session.getString("text");
51 tweet.author = session.getString("from_user");
52 tweets.add(tweet);
53 }
54 }
55 } catch (Exception e) {
56 Log.e("TwitterFeedActivity", "Error loading JSON", e);
57 }
58 return null;
59 }
60 @Override
61 protected void onPostExecute(Void result) {
62 progressDialog.dismiss();
63 setListAdapter(new TweetListAdaptor(
64 TwitterFeedActivity.this, R.layout.list_item, tweets));
65 }
66 }
67 private class TweetListAdaptor extends ArrayAdapter&lt;Tweet&gt; {
68 private ArrayList&lt;Tweet&gt; tweets;
69 public TweetListAdaptor(Context context,
70 int textViewResourceId,
71 ArrayList&lt;Tweet&gt; items) {
72 super(context, textViewResourceId, items);
73 this.tweets = items;
74 }
75 @Override
76 public View getView(int position, View convertView, ViewGroup parent) {
77 View v = convertView;
78 if (v == null) {
79 LayoutInflater vi = (LayoutInflater)
80 getSystemService(Context.LAYOUT_INFLATER_SERVICE);
81 v = vi.inflate(R.layout.list_item, null);
82 }
83 Tweet o = tweets.get(position);
84 TextView tt = (TextView) v.findViewById(R.id.toptext);
85 TextView bt = (TextView) v.findViewById(R.id.bottomtext);
86 tt.setText(o.content);
87 bt.setText(o.author);
88 return v;
89 }
90 }
91 }

You should now have a complete app requesting the Twitter data in the background.

The AsyncTask has quite a few more features to explore. You can be sure we will cover those in future articles. In the meantime you should read the excellent Android document covering these classes at Android Developers site.

Hello Android

January 4th, 2012

Hello Android

Writing your first app and seeing it running on your phone is only half the fun when it comes to Android. It’s relatively simple to have your app up and live in the Android Market, being used by Android users almost instantly.

Head over to http://market.android.com/publish and using your Google Account, register as a developer in the Android Market. The registration process is immediate and requires a one-off registration fee of $25.

By the end of this article, you’ll be ready to submit an Android app to the Market (although it’s probably best to avoid submitting this HelloWorld-style app that we’re about to create).

Setting Up Your Development Environment

Java developers, especially those using Eclipse, will have an easy transition to the Android development world. Most apps are written in Java (you can drop down to using native C), and it’s typical for development to be done within the Eclipse IDE due to the tooling support provided by Google (although everything can be done outside the IDE from the command line). Android development is supported on the three major operating systems: Windows (XP, Vista, and 7), Mac OS X, and Linux.

In order to set up your environment, you’ll need to download and install the following:

  • A Java Development Kit (JDK 5 or JDK 6)—the Java Runtime Environment (JRE) alone is not enough. You can download the specific JDK for your system from http://java.sun.com/javase/downloads/index.jsp.
  • Eclipse 3.5 (Galileo), which can be downloaded from http://www.eclipse.org/downloads/. “Classic” is the recommended version.
  • Android SDK Tools available from http://developer.android.com/sdk/index.html. Take note where this is installed or unzipped for the next step.
  • Android Developer Tools (ADT)—Eclipse Plugin, which needs to be installed from inside Eclipse:
    • From the Help menu, click on Install New Software, then select Add.
    • In the dialog box, enter ADT Plugin for the Name and https://dl-ssl.google.com/android/eclipse/ in Location; then press OK.
    • Select Developer Tools and click Next, and Next again when presented with the items to be installed.
    • Read and accept the license terms, and click Finish.

When the installation is complete, restart Eclipse.

Now configure the installed plugin by clicking on the Window menu and selecting Preferences. If you’re on a Mac, select Eclipse -> Preferences.

Select Android, and then for the SDK Location, browse to where you installed the Android SDK Tools, and select that. Click Apply, then OK.

Using the tools now installed, you need to install the SDK components. This is done using the Android SDK and AVD Manager found under the Window menu in Eclipse. Launch the manager and select Available packages. Then select DocumentationSDK Platform Android 2.3, and Samples for SDK API 9; click Install Selected.

Running the Emulator

Now that you have all the tools required to started developing and running Android apps, you need to create a virtual device for your apps to run on in the Android Emulator. An Android Virtual Device (AVD) defines a device profile that the emulator can use when running your apps. You can also create multiple AVDs to test against, which comes in handy when you want to test your app on different-sized screens and various versions of the SDK.

To create an AVD, select Virtual Devices from the Android SDK and AVD Manager, and click New. Give the device a name and select the target SDK from the drop-down. Here, you’re also able to select different screen sizes and emulator storage sizes; for now, we’ll leave everything as the default and click Create AVD.

Now you’re able to run the emulator by selecting the created AVD and clicking Start, and then Launch. After some time, you’ll see the emulator running; you’re now able to run some of the built-in apps.

Creating a Project

Leaving the Emulator running, restart Eclipse so as to create our first Android project. Once Eclipse has finished loading, go to File -> New -> Other -> Android and select Android Project.

Fill in the Project and Application names, and then enter a package name for the app. This package will not only become the top-level Java package for your source files, but also provides a unique identifier for your app. No two apps can have the same package identifier installed on the phone at the same time, and the same goes for apps submitted to the Android Market.

With Create Activity selected, provide a name for the Java class that will become the entry point to your app, and click Finish.

Explore the contents of the generated project. You will find various Java, XML, and configuration files.

This is a good time to explain three key concepts used in Android app development.

Activity (HelloWorldActivity.java)—An Android Activity is a single-focused task that makes up part of your app. The Activity will display a user interface in the supplied Window, and interact with the user to perform the task. A single Activity could be displaying a list of emails or showing a map of the current location.

Typically, multiple Activities together form a complete Android application.

The generated Activity extends from the class android.app.Activity and overrides a single method, onCreate. Activities are driven by events coming from the Android operating system, moving the Activity through different stages of its life cycle. The onCreate method is called when the Activity is being created with the intention of being the current running Activity.

It’s worth becoming familiar with the life cycle of an Activity and the methods that can be overridden as detailed in the Android developer docs.

Manifest (AndroidManifest.xml)—This is the central configuration file required by Android to understand the various pieces of your app and how they fit together. Take a look at the generated Manifest, where you’ll see:

  • package="com.sitepoint" which forms the unique identifier of the app
  • <application ... > contains the attributes required for the app icon and name as it appears on the phone
  • <activity ... > is where the single Activity that was generated is described with attributes for the class name (relative to the app package), and a display label for the Activity.
  • <intent filter> these XML elements indicate that this Activity is the entry point for your app when it’s launched:
    • <action android:name="android.intent.action.MAIN" />
    • <category android:name="android.intent.category.LAUNCHER" />

Intents—Android is designed in such a way that apps can call out to other installed apps without having to know the specific details of their interfaces. This is achieved using the concept of Intents and Intent Filters. An Intent is an abstract description of an action (such as VIEW, SEND, EDIT), and typically references some data on which the action is to be performed (for example, a Contact in the address book).

Activities can create Intents as a way of passing responsibility for a task onto other Activities. This can be either within the same app (such as going from an Activity that displays a list of contacts to an Activity that displays the details of the single selected contact) or out to an external app (when, for example, you want to display a PDF using an installed PDF viewer).

Activities advertise their abilities to handle combinations of actions and data types through Intent Filters. Our generated Activity advertised that it’s able to handle a MAIN action when the app is being launched. A PDF viewer may advertise that it can display data of type PDF. If two apps advertise the same ability, Android will prompt the user to select which one they want to use. The Intent is run, and can make the selection the default as an option.

Running and Debugging

Now let’s run the app in the emulator, which you should already have running. Select the project in Eclipse, and from the Run menu, select Run; then select Android Application and OK in the dialog. While the app is loading (or the emulator starts up again if you closed it), you should add some of the Android-specific views to your current Eclipse perspective. You can add them from Window -> Show View -> Other -> Android. I typically add DevicesEmulator Control, and LogCat.

From the Devices view, you can see any emulators or phones you have plugged into your system that are available to debug apps on. You’ll also be able to see the processes currently running along with your own, identified by the package name you gave your app. If you select the emulator in this view and then move to the LogCat view, you’ll see all the logging that the system has been writing.

This view is extremely useful for debugging your apps. It allows you to create filters, so you can switch between seeing different levels of logging (warning, debug, fatal) and different tags. (Typically, an app will output logging with a tag that’s the same as the class name for where the logging is coming from).

Switch back to the emulator, and you should now see the app running as pictured below.

Once you’ve figured out a desirable functionality, writing an app for Android is largely a matter of ensuring you have the right tools installed, and then configuring them to do the hard work for you. After that, you can submit your app to the Market for other Android users to pick up.