Dec/10
2011

I’m pleased to announce a game we’ve been working on is now out. A collaboration between The Creation Agency and Bitmode (my previous home), we bring you The Great Snowball Fight!

Snowball Fight

The game is played over Google Maps, launching virtual snowballs at unsuspecting players in order to rank up, earn points and even win prizes from retailers you hit. You can also add buddies, connect via Facebook and receive special powerups.

Utilising Flash with AIR 3 and native extensions, we were able to build a game for iOS, Android and also PC. The game uses native extensions for deeper platform integration, such as the compass sensor or push notifications, as well as GPS to pin-point your location.

Head on over to the site to download the game and get throwing some snowballs!

Update: See comments for iOS compass extension source.

Dec/10
2011

I recently wrote a tutorial for .NET Magazine covering styling and theming components in Android. This includes how to use resolution independent units so that your UI looks crisp across a wide range of devices and 9-patch images for smooth scaling.

Here’s a link to the article.

Dec/03
2011

I was absolutely delighted to hear that the app I put together for the Vodafone Smart Accessibility Awards has been made a finalist. The app, “Are You OK” falls under the wellbeing category. If you’re not familar with the awards, the idea is to improve the lives of the elderly or disabled through technology.

Are You OK is a simple app that was inspired by the panic button pendants many elderly use in their homes. The button communicates with a base-station plugged into the phone which contacts an emergency call center and and a voice can be heard over the speakerphone. The problem is these buttons are often left lying around out of reach, and many hours, or at worst days can go by before they get help after something like a fall. On top of this there’s a monthly fee for the service.

Are You OK works in reverse. It has an easily configurable alarm which goes off every X hours throughout the day, asking if they are OK with two big buttons, yes or no. If they hit no or fail to get to the phone within a certain time, it sends a text message to chosen friends or family asking them to check in by phone or by dropping by.

Tomorrow I’m off to Brussels to present the app before a panel. Here’s hoping it all goes well and if I’m very lucky I’ll get to bring back good news!

You can view the final 12 apps here.

Oct/12
2011

The Android Workshop is coming to TechHub in London, tickets are now available for Thursday 24th and Friday 25th of November this year. It’s a full 2 day introduction covering a wide range of topics from layouts and widgets to styling and database access, for more info please head over to the site. Sign up fast to guarantee your Early Bird price, or add yourself to the mailing list for future events.

Finally there’s the Twitter account @androidws, feel free to shoot over any questions you may have or drop them in the comment form below. Look forward to seeing you there.

Sep/26
2011

Earlier today Paulo Fierro blogged an example of how to build a dynamic application cache manifest for HTML5 web apps using Ruby.

A cache manifest is a text file that browsers look for in order to determine which files to store locally on the device, this lets you open the site/app offline, great for web apps (on iOS bookmarking a site to the home screen also let’s you specify an icon and removes browser chrome). Creating a cache manifest dynamically means that you don’t have to worry about modifying a text file every time you add or remove a file from the app.

This prompted me to upload my PHP version that works pretty much in the same way. I built it for an iPad web app that needed to run completely offline collecting peoples details at a car show (it later synced data with a server when it found a connection). It’s pretty basic, it just creates an MD5 of all the files in a directory (apart from excluded files, including itself!), so that when one is changed, either the content or the name, the MD5 value changes and that results in the contents of the manifest changing, causing the browser to re-evaluate it.

Below is the dynamic manifest, let’s call it “cache.manifest.php":

PHP:

<?php 
    header("Cache-Control: max-age=0, no-cache, no-store, must-revalidate");
    header("Pragma: no-cache");
    header("Expires: Wed, 11 Jan 1984 05:00:00 GMT");
    header('Content-type: text/cache-manifest'); 
    
    $hashes "";
    
    function printFiles$path '.'$level ){ 
        global $hashes;
        $ignore array('.''..','.htaccess','cache.manifest.php','index.html','submit.php'"video.mp4");  
 
        $dh = @opendir$path ); 
 
        while( false !== ( $file readdir$dh ) ) ){ 
            if( !in_array$file$ignore ) ){ 
                if( is_dir"$path/$file) ){ 
                    printFiles"$path/$file", ($level+1) ); 
                } else { 
                    $hashes .= md5_file("$path/$file");
                    echo $path."/".$file."\n";
                } 
            } 
        } 
 
        closedir$dh ); 
    }
?>
CACHE MANIFEST
<?php 
printFiles('.');
// version hash changes automatically when files are modified
echo "#VersionHash: " md5($hashes) . "\n";
?>
 
NETWORK:
./submit.php
./video.mp4
 
FALLBACK:
./video.mp4 ./images/offline.jpg
./images/video.jpg ./images/offline.jpg

Remember that cache space is extremely limited. I think it was about 5mb on the iPad first gen. If you need more space you’ll have to use local SQLLite (perhaps storing blobs) and request more DB space from the user.

So you probably don’t want to be including things like video files, you also don’t want to cache the output of dynamic server-side scripts. This is what the NETWORK and FALLBACK portions of the manifest are used for. You can force the browser to only look to the network for certain files, and also provide fallbacks for files it won’t find offline (in the case above, it shows an offline image in place of the video).

To make the browser look for the manifest, you just add the manifest attribute to the HTML tag:

<html manifest="cache.manifest.php">

Now when it comes to actually forcing your client app to check for updates, the following JavaScript should provide some insights. Sorry it’s a bit rough and ready, but it should illustrate how you might invoke an update:

Code:

var cacheStatus = getCacheStatus(window.applicationCache.status);
  console.log("App cache status: " + cacheStatus);
  
  var appCachedHandler = function () {
    console.log("AppCache cached");
    dialog.dialog("close");
  }
  var updateReadyHandler = function() {
    console.log("AppCache update ready");
    
    $("#versionImg").attr("src", src="images/update_available.png");
    $("#versionImg").css("visibility", "visible");
    
    dialog.dialog("close");
      
    if(  !isSyncing && confirm("Update available, update now?") ) {
      window.applicationCache.update();
      window.applicationCache.swapCache();
      window.location.reload(true);
    }
  }
  var downloadingCacheHandler = function() {
    console.log("AppCache downloading...");
    dialog.dialog({modal: true, title: 'Downloading update...'});
      
    $("#versionImg").attr("src", src="images/loading_small.gif");
    $("#versionImg").css("visibility", "visible");
  }
  var cacheErrorHandler = function(obj) {
    console.log("AppCache error " + obj);
    dialog.dialog({modal: true, title: 'Cache error:'+obj});
  }
  window.applicationCache.addEventListener('cached', appCachedHandler, false);
  window.applicationCache.addEventListener('updateready', updateReadyHandler, false);
  window.applicationCache.addEventListener('downloading', downloadingCacheHandler, false);
  window.applicationCache.addEventListener('onerror', cacheErrorHandler, false);