Update: There is a problem with this method. It appears that the Android framework will not pickup the bool values using any type screen size modifier (e.g. sw600dp or xlarge) because they can change at runtime. It won’t give you an error, instead it’ll just completely ignore the resource and default to true. You can of course achieve the same results in other ways but unfortunately they’re not quite as clean as what i had hoped to achieve below. Sorry!

I already created a tablet app a while back when Honeycomb was first released but since then I’ve been working on phone only applications. Between then and now, the compatibility library has been released and a new way of handling screen sizes has been introduced into the Android framework. Below is a recipe on how to use these features to architect a single apk app that will run on both phone and tablets. Credit to Nick Butcher for inspiration from his talk at Droidcon UK 2011.

1) Encapsulate the functionality that you had (or would have) in your activities into Fragments
A Fragment is, generally, a chunk of a user interface with it’s own lifecycle.  This sounds similar to how you might describe an activity doesn’t it? In fact, if you’re adapting an existing app, you can pretty much cut and paste your code from your old activity into your new Fragment. Then your old activity is only responsible for instantiating your new Fragment and listening to any events that it might trigger.

2) Create completely separate Activities to handle single pane layouts vs dual pane layouts (i.e. phone vs tablet)
Don’t think about hdpi, large or xlarge buckets any more. Think more like a responsive web designer e.g. here is my single pane layout for screens less than 600dp and here is my dual pane layout for screens wider than 600dp.

By way of example, an imdb style app might have two fragments: MovieListFragment (to show a list of movies) and MovieDetailFragment (to show the movie detail).

When designing for the single pane layout (e.g. for phones) you would most likely have two activities:

  • SingleMovieListActivity – which is where the MovieListFragment would live and
  • SingleMovieDetailActivity – which is where the MovieDetailFragment would live

Pretty simple eh? For the dual pane layout (e.g. tablets) you would have something like:

  • DualHomeActivity – which would house both Fragments; MovieListFragment (on the left) and MovieDetailFragment (on the right).

Keeping them separate means that you don’t have messy code within your activites to detect which screen mode you are in before you can show or act on anything.

3) Use the (force) framework
You don’t need a splash activity to detect how many pixels are on screen before you forward to an appropriate starter activity. Simply add something like android:enabled=”@bool/single_pane” to any single pane activity elements within your Android Manifest. Then create the file res/values/bools.xml with the following contents:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="dual_pane">false</bool>
<bool name="single_pane">true</bool>
</resources>

Handling the dual screen activities is also quite simple. Add android:enabled=”@bool/dual_pane” to any dual screen activity elements within your Android manifest. Then create the file res/values-sw600dp/bools.xml with the following contents:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="dual_pane">true</bool>
<bool name="single_pane">false</bool>
</resources>

Now if your app is started on a device that has a width of at least 600dp (e.g. a tablet) then the framework will enable all of your dual pane activities and disable all of the single pane ones. Conversely, if your app is started on a device with less than 600dp then all single pane activities will be enabled and the dual pane ones will be disabled.

Note that the sw600dp modifier will only work for Android 3.2 and above so you should also copy the above bools.xml to res/values-xlarge/bools.xml to cater for the extra large screens in older versions of Android.

4) Decouple communication
So you have all these reusable fragments…but they can exist in different activities depending on whether you’re running on a device that has a width of more or less than 600dp. How does your fragment know whether to transition to a new screen or whether to animate in a new fragment when a movie is selected? The answer of course is that it doesn’t and shouldn’t.

The enclosing activity knows whether you are in single vs dual pane mode so you need a clean way to communicate your event (e.g. movie selected) to this enclosing activity. There are a few ways to do this but my favoured way is to use Broadcast Intents. Your enclosing activity (which is listening for these defined events) can intercept a broadcast intent and associated parameters and then decide whether to transition to a new activity (if in a single pane activity) or whether to replace the currently showing MovieDetailFragment (if in a dual pane activity).

Simples.

There seems to be a lot of confusion about how do this. Actually it’s pretty easy:

  1. Reboot your machine and hold down CMD+R.
  2. Choose the option relating to Disk Utility and erase the Macintosh HD.
  3. Close Disk Utility and from the list of options, reinstall Lion.

(Note, you’ll need to hook up your machine to a wifi Hotspot so that it can download the entire Lion image from the internet…zzzzzzz)

 

Please note that all credit goes to Sun Chen for this solution (blogpost here: http://chensun.net/android-development/install-sqlite3-on-google-nexus-one/54/).

I simply applied the same technique to my Nexus S and have reproduced the steps below for my own future benefit.

[Notice! You must have root access on your Nexus One / Nexus S.]

1. Download sqlite3, which comes with SuperOneClickv1.7-ShortFuse, and copy it to your SD card.

2. Connect your phone to your computer. Open a Command Prompt, and type the following commands:

adb shell
$ su
# mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
# dd if=/sdcard/sqlite3 of=/system/bin/sqlite3
# chmod 4755 /system/bin/sqlite3
# mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system

Done! Now you can use sqlite3 to examine database on your Nexus One / Nexus S from a Remote Shell or even from an Android Terminal Emulator.

I’ve been out of action for the past 8 weeks.  My mother was diagnosed with Ovarian cancer this year and developed a serious complication after an operation to remove a tumor 8 weeks ago.  Since then she’s been fighting for her life, against the odds, in intensive care at Galway University Hospital in Ireland.

I’m so thankful to all the amazing surgeons, doctors, nurses and medical staff.  Thanks to them, Mum has pulled through and is now well on the way to making a full recovery.

I can’t wait to get stuck into work again and have some exciting projects and ideas lined up!

Google IO is nearly upon us and just yesterday the session schedule was released code.google.com/events/io/2010/session-schedule.html. You’ll notice that there are three Android sessions on day two that are yet to be disclosed!

Here’s my prediction for how the event is going to roll.

Day One:
At the keynote, Google will make lots of cool announcements across their product and technology range. HTML5 and Android will feature heavily. For Android, I think that they’ll announce the successor to the Nexus One which will be aimed at the enterprise market.  This device will include encryption and all the features that are currently missing for a business phone e.g. better exchange and docs integration, perhaps a front facing camera for video calls and a physical keyboard.  They’ll announce a new version of the Android OS (Froyo) for sure, see www.informationweek.com/blog/main/archives/2010/04/evidence_of_and.html

Day Two:
Last year the day two keynote was devoted to Wave, this year I think that the spotlight will fall on Android.  My prediction is that Google will announce a their answer to the iPad. To boot, they’ll show us an awesome new Android market that will be available on the new tablet as well as all Android phones (Google does not allow the marketplace in its current form on tablet devices) .  I’m hoping that they’ll also announce a new visual designer for Android.  This is something that has been sorely missing for some time and will be a great demo to show the general audience how easy it is to develop for Android.

So, the three undisclosed Android sessions?

1) Developing applications using the new UI designer
2) An advanced session on the new Market
3) A session devoted to developing for the “Tablet”. Yes – there is already a session on “Casting a wide net: how to target all Android devices” but the tablet is a completely different form factor and will need special consideration.

Whether this all happens or not, we’ll just have to wait and see. But this is the stuff that I’m looking for as a developer.

Yours,

Columbo

With the verbosity (I mean that in a good way) of the Android APIs, you’d think that it would be extremely straightforward to get a handle on the ip address for your android device.  It’s not – but with the code below you can obtain this information in the most efficient possible way using some math to translate the returned integer from WifiInfo into it’s component string ip address.

WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = intToIp(ipAddress);

....................

public String intToIp(int i) {
   return ((i >> 24 ) & 0xFF ) + "." +
               ((i >> 16 ) & 0xFF) + "." +
               ((i >> 8 ) & 0xFF) + "." +
               ( i & 0xFF) ;
}

WhereCamp EU 2010

February 23, 2010

I’m very much looking forward to WhereCamp EU this year which is being held at the Guardian offices in London on the 12th & 13th March 2010.

WhereCamp Europe is an unconference; inspired by FooCamp and the Silicon Valley WhereCamp which traditionally follows Where 2.0. It’s open to everyone and you drive the agenda and the sessions. It’s what you make it, so come along, listen, contribute and speak.

The event is at capacity but you can join the wait list http://wherecamp.eu/blog/2010/02/waiting-list-open/ and hope that some spots become available.

Sponsored by the likes of Google, Bing and data.gov the event is totally free (unlike TED which will set you back $6000 per ticket!).  Hope to see you there!