Showing posts with label android. Show all posts

Monster dash - Making an android game with my son

At the start of last year, 2017, I set a resolution, of sorts, to build a mobile app with my older boy. He was just getting into playing games on mobile phones and tablets, and lots of them were just simple side scrolling platform games, where your character just had to run and avoid minor obstacles and perils.

Needless to say, whilst I managed to start it, it wasn't until after Easter this year that I actually managed to complete it. Now, this did appear to pose one problem: over a year later since the idea, my boy was playing far more sophisticated games so when I pitched the idea of making a mobile game together, his plans went far beyond the simple side scrolling platform game I had in mind! I was a bit unsure if he was going to be totally underwhelmed by the finished product that we were making, but in the end, having seen his creation come to life he was thoroughly pleased.



When we finally had something working (albeit fairly primitive) he took it into school as a show-and-tell, and surprisingly, the other children were all very impressed - I assume just because of the feat of making a game, despite in paling in comparison to actual games they undoubtedly all played.





Anyway, the source code for the game is all on Github (maybe one day we will make a game and publish it, so he can see that process and actually have other people play his game) and can be found here: https://github.com/robhinds/monster-dash.  I can't take much credit for the legwork on this one though - knowing that the game concept I was after was very simple, I figured there would be a how-to somewhere lurking on the internet, and sure enough we stumbled upon this: http://williammora.com/a-running-game-with-libgdx-part-1 - If you want to have a go I would recommend following William's series of articles explaining the hows and whats. I modified (read mangled) his source code a bit, simplified parts and added flourishes here and there, but its very similar in theory.



To be honest, the hardest part was cleaning up the images - He drew them, then I just snapped them with my phone, used a selection of online tools to remove backgrounds and chop them up for my animation, then loaded them into the app.

My boy really enjoyed working on it, and still asks if we can make another app, with even grander ideas, so I highly recommend it!


Android: Building a cloud based quiz application

A long time ago, when Android was still in its infancy (1.5 I think..) I built and open sourced a basic quiz app.  The app was just a basic multiple choice question-answer app, driven from some questions in the database, but it did ok - it has had over 10k downloads on the app store, and the blog post tutorial here is still one of the most popular articles.

But here we are, Android 5.0 is released and the state of Android development is very different now. But I didn't really want to just re-skin/tweak the old app and push it out again - and I also wanted to write up some notes on using parse.com as a backend service - so this seemed like a good opportunity.

The source code for the app is all on GitHub.


The goal

So the aim is to create a an android app quiz game, but rather than using local storage, using the cloud to power the questions. This avoids the need for lots of boiler plate DB code and also makes it easier for us to update questions.  The tutorial will be broken into two parts - the first part will be basic quiz stuff with cloud questions, the second part will enhance the app to support user login and to track scores to allow users to compete against each other.


Parse

Before you start the tutorial, you need to get an account setup at parse.com - its a cloud DB/backend as a service that was recently bought by Facebook. They allow real easy setup of DBs and provide a load of nice libraries/APIs to really easily interact with their endpoints across lots of platforms (its also incredibly well priced -the free tiew is really good and if you find your mobile app is going beyond that then you can probably think about monetising the app!).  All you need to do is head over there, sign-up and then create a new app - all you need to do is give it a name and hey presto!  You can either make a note of the keys then, or come back and grab them later. There are no other changes you need to make now, as that will get handled from our source code. The only other thing to do is to download the parse android library to make use of their sdk in android (if you have grabbed the source code from GitHub then you will not have to worry about these)



OK, lets get started!

Again, I am not going to spend a lot of time covering the real basics of Android and only really mention the things of note or that are different from standard application development - hopefully the code & general explanation will be clear enough to get an understanding of what is going on.


Android manifest
First, lets get our AndroidManifest.xml file configured.  The only things to note here are the permissions we are setting - we will request internet access and network state permissions. Also worth noting that I have set the min sdk for my sample app at version 16.


Our Application class
We will have to create a custom implementation of the Android Application class. This class is instantiated on application startup, and hopefully if you are looking at Android development you should be familiar with this class.  We will do a couple of things in this class:

  1. Register our parse.com application with out secret keys
  2. Initialise the Parse library and our domain objects
  3. Try to fetch all the questions for the quiz and store them for offline usage 
  4. Create a GamePlay object, that will keep track of the state of the current game in progress
First lets look at the Parse setup - this is standard parse boilerplate and is covered in parse docs and sample apps - you just need to add your ID/Key here (also note, we have just registered the Parse object class Question - this is our domain object - like a JPA entity etc - if we add more domain objects they need to be added here too)

Next we will make a call to parse.com to fetch the questions from our cloud API - we will save this in the background (make an asynchronous call) and "pin it" to make it available for offline usage. Also note that we do not un-pin existing questions until we have successfully found new ones - that way users should always have questions once they have successfully loaded them the first time.
Hopefully the above is quite clear - the parse libraries are quite straight forward to understand - we create a query (typed Question) and then call findInBackground and implement an on success handler.


Domain objects: Question
Parse library provides a nice interface to create POJOs to model your domain model, if you are familiar with JPA/Hibernate/etc and the approach of POJOs representing a domain model its much like this. Using these classes you can easily query/load/save data from the cloud by just using these objects. You will have spotted that in the query we use in the application class to load all our questions we just run a plain query with the Question class - this, as you should expect, will just retrieve all Question objects from your cloud table (parse). The domain models are just an annotated POJO, and you just define appropriate getter/setters for the fields you want to include.


Welcome activity
Now we are into Android basic stuff really - we have setup parse and fetched the questions for local usage, now we just need a basic menu to start the quiz and some activities to display the questions and the end results.

We will just apply the layout and then implement a method to handle the button clicks. For this tutorial we are skipping the high score stuff and just playing the quiz.
All we need to do is reset the current GamePlay object and grab the questions from the local store (by this point they should be updated from the cloud so no problems, then kick off the quiz!


Question activity
There is nothing really interesting to see here - it's all on github if you want to take a look in detail (or have already downloaded and working along) - This is just a standard Android activity that pulls out the question and possible answers and presents them.




This just progresses along fairly simply, until it gets to the end of the quiz and then it presents a simple screen saying the score - all this stuff can be tweaked/styled etc - but there are the basics for a cloud powered multiple choice quiz app!


Creating the questions

All the questions will be stored in the cloud in parse.com - once you have a look at the interface, it should be pretty clear - you can easily create the data for questions either manually or by importing a csv/json file.



You will need to login to your parse account and the quiz app and create a Question class. This will just match the domain POJO we have created. Just login, go to "CORE" then "DATA" Then select "+ Add Class", adda a custom class called "Question" (this must be exactly the same as the name provided in the POJO annotation for the Question class).. Then select "Add Col" and add the fields to match the POJO (question[string], option1[string], etc).  Once you have the class/table added on parse, you can simply add data by selecting "Add Row" and just manually entering the data, or using the import function.



Source code

Tech: Building an RSS reader for Android (RIP Google Reader)

This tutorial will walk through building an RSS reader on the Android platform (focusing on 3.0 + as it will be using Fragments). All the code is available as a complete, working Android app that you can fork/download and fire up straight away on a compatible Android device/emulator. So feel free to go grab that from GitHub before continuing.

It is not an unusual requirement for mobile apps these days to be able to consume an RSS feed from another site (or many) to aggregate the content -  Or maybe you just want to build your own Android app now that Google has announced it will be retiring Reader.

Those of you who have worked with RSS in other JVM languages will know that there are plenty of libraries available that can handle parsing RSS - however, because the android platform doesn't actually contain all the core java classes, almost all of the RSS libraries have not been supported.

Fear not though, as Java's SAX parser is available, so with a bit of code we can get a custom RSS parser up and running in no time!

This walk through will cover off the basics of getting an RSS reader app up and running quickly and will also cover some details of Android's fragment system for tablet optimization as well as some things to watch out for (such as changes in the platform that mean network operations cannot be run in the main thread, which requires some tweaking if you have worked on earlier versions).

All the code for the app is also available on our GitHub so feel free to fork that and try loading it up on your Android device/emulator.

Parsing an RSS Feed:


So to get started we will look at parsing the feed - if you have any experience parsing XML using SAX in Java then you will know how easy this is. All we need to do is to tell the parser which XML nodes we care about, and what to do with them.

If  you have never implemented a SAX parser before, there are three primary methods that we will override: 
  • startElement() - This is called by the parser every time a new XML node is found
  • endElement() - This is called by the parser every time an XML node is closed (e.g. </.. )
  • chars() - this is called when characters are found between nodes



Because we only really care about capturing data from the leaf nodes, our startElement() method is left empty. The chars() element has to be watched, as there is no guarantee when it will be called (e.g. in a node like hello world  this method might be called several times between the start and end) so every time we will just append the contents to a StringBuffer - that way we can be sure that we will have captured all the data in the node.  By the time the endElement() method is called, we know that we have the contents of the node itself, and we just have to store the data.  At this point, we just quickly knocked up a POJO with the attributes that we wanted to capture - the Strings that we match on are the node names from the ATOM RSS feed (that Blogger uses) - if you are using another feed, just have a quick look at the feed and update the node names appropriately.

Using our Feed in an Android App

So, that was easy right? Once that parser has run through (and you could use that code standalone in any java app really) then you will have a list of Java objects that have the core details about the latest blog posts on the feed (title, author, datecreated, content, etc) - So now lets look at using it in an Android app.

We will assume a basic understanding of the Android SDK and the concept of Fragments, so won't go back to basics with that stuff.

What we will do, is create a basic ListFragment and an RSSService class that we will use to populate the list. In our ListFragment we will simply tell our RSS service to populate the list:



Simple right?

Let's take a look at what our helpful RSS service is doing for us.



The first thing to note is that this class is extending Android's AsyncTask- The reason for this is that since Android 3.0, you are no longer able to perform network operations in the main application thread, so being as our class is going to have to fetch some RSS feeds we are going to have to spin off a new thread.

As you can see, the constructor just sets some context info that we will use later on, and then builds a progress dialogue - this is then displayed in the onPreExecute() method - This lets us show a "loading" spinning disk whilst we fetch the data.

Android's AsyncTask's primary method that handles the actual work that you want to do asynchronously is called "doInBackground()" - In our case, this is simple - we just invoke our SAX RSS parser and fetch our feed data:



Finally, we will override the "onPostExecute()" method of the async class to use our newly fetched list to populate our ListFragment.  You note how when we overrode the doInBackground() method earlier we set the return to List of Articles (where Article is my simple POJO containing my RSS blog post info) - well this must correspond to the argument of the "onPostExecute()" method, which looks like this:



Actually, all we really needed to do in this method would be pass our new List or articles to the ListFragment and notify it of the change as below:



However, in our application we have added a bit more sugar on the app - and we have actually backed the app with a simple DB that records the unique IDs of the posts and tracks whether or not they have been read to provide a nicer highlighting of listed blog posts.

So that's it - there's plenty more you can add to your RSS reader app, such as storing posts for reading later, and supporting multiple feeds/feed types - but feel free to fork the code on GitHub, or just download on to your android device to enjoy all our NerdAbility updates!

Application running in Andriod emulator
RSS application running in an Andriod  tablet emulator




Google kill off Google TV (in favour of Android TV)



Following on from expectations on the TV front, Google have just announced that they are end-of-life-ing Google TV as Android TV is fully operational as part of Android 5.0 - expect they are working with some OEMs right now to start getting some interesting devices launched..



Christmas Sandwiches & an Android app


Following some banter on Twitter last week about christmas sandwiches (we have something of a tradition of eating, reviewing and ranking as many christmas sandwiches as we can find in the build up to christmas), I set a goal of creating a mobile app to help with this before the end of the week.

So, over the course of three nights (mostly commuting time) I built and launched a Christmas Sandwich rating app.  The app is basic. It let's people review sandwiches, and then read other people's reviews of sandwiches and see average ratings given to each sandwich.



It is an Android app that uses parse.com as the cloud backend to allow users to view other users reviews. At some point in the future, when I get the chance, I will put the code on github and write another post about what is going on, but in the meantime..

Get the app on the Play store

Enjoy!





iWatch & wearable tech

Much has been made lately of Apple's latest announcements of the iPhone 6 and their new Apple watch, and really, I'm pretty late to the party on this one.  I don't normally comment much on Apple announcements, but this time I fancied a rant.


Personally, it's not to my tastes. I know the strap is inter-changeable, and you can change the watch face screen, but I'm not a fan.  In part, because I am more of a fan of classic watch design (so really, some of the photos of the Moto-360 look closer to what I would want a smartwatch to look like), but generally, it feels a little garish, and a bit like something designed 5 years ago.  The curved, almost bubble like glass shape of the device, the square watch face.



I'm not sure what it is.

Maybe its because it feels at odds with current web design trends on flat design. Maybe its because it feels like the original iPhone matured/evolved from it's original curved shape to the current sharper, flatter designed shape and this still seems to hark back to the original iPhone design.

Anyway, as an aside, I think if I was going to spend hundreds on a flash-y digital watch, I would quite like this one:



Sure, I can't check emails on it, but it looks nice.  But then I'm not really someone who should be commenting on style and fashion, so will stick to tech trends..


Is wearable tech the next big thing?


Honestly, I think probably not. Not for the time being at least. I'm sure some smart people will work the market out eventually, but for the time being, and with the current incarnations of smartwatches, I don't think the market is really there.


So, here's the thing - I'm not really sure what the point of the apple watch is (and I guess that is what needs to be cracked before the market can take off). I think, it's going to face the same challenges that tablets have faced - it needs to grow up and work out what it is. It needs to understand what its purpose is and find its niche - it's not going to be good enough to be the same as a smartphone but a different form.


Let's have a look at the markets:

Smartphones:
  • Defined and fairly standard "upgrade-cycles" - the expectation and standard of upgrading devices every 12-24 months is fairly established in the west, and this is both driving existing customers to newer, better devices, but is also slowly migrating existing feature phone users to smartphones.
  • Everyone has one - at its core, as a phone/communication device it provides that roaming communication functionality and is at least one per-person (not shared)
  • Convenience - easy to carry and roam.

Tablets:
  • No real defined upgrade-cycle (in terms of device contracts) and too early to see patterns being established - optimistically will fall back to traditional PC cycles of approximately every 5 years
  • Not per-person devices - You might be safe to typically expect everyone in an average household to have a (smart)phone, but probably only one/two tablets per house.
  • It doesn't solve any real problem - sure, its a little better for watching movies than a smartphone, but apps, browsing, emails and other comms are not noticably better. Further, tasks that might need greater control, or screen real estate - like creating spreadsheets, or presentation slides for example - people still fall back on using regular PCs. There needs to be a purpose/task/app that is made for a tablet sized device - where tablets solve a problem that only they can. As of yet, we're still waiting.

Smartwatches:
  • Still yet to see upgrade cycles - will be interesting if carriers/manufacturers try to tie these into existing mobile contract structuring. It will make adoption even harder if they try to sell it with a 1-2 year lifecycle for sure.
  • Aimed to be per-person, as a sidekick to your smartphone - but if all it offers is your smartphone in a slightly different form, its again going to be a tough sell - Sure, its slightly more convenient than getting your phone out of your pocket, but that seems like a dubious USP to base an entire market on.
  • It doesn't solve a problem - Again, there needs to be a task/area/job where the smart watch is the answer. Where it fills a need that simply can't be filled by a smartphone (or can be, but is a pain in the ass)



For a change, let's have a look at some smartphone/tablet data:


Tablet sales struggle: Apple iPad growth projections by quarter

(Source: Computer World: As tablet growth slows, Apple may face a year-long iPad sales contraction )

Just focusing on Apple for the moment, Benedict Evans presents some interesting data analysis of their recent sales/revenue numbers. Firstly, we see that iPad sales have flattened out and basically settled where they are for the last two years, whilst iPhones have continued to see growth year on year:

http://ben-evans.com/benedictevans/2014/4/25/ipad-growth
(Source: Benedict Evans - iPad growth - Apple's trailing 12months sales)


More generally, if we look at the comparison of sales across PC vs Android/Apple smartphones, we see that PCs have levelled out, but the smartphone continues to see huge growth:

http://ben-evans.com/benedictevans/2014/4/25/ipad-growth
(Source: Benedict Evans - iPad growth - General shipping - PCs vs Smartphones)




It really looks like the smartphone market is continuing to surge. With standard upgrade-cycles, and low end Android smartphones becoming more widely accessible, this trend seems set to continue.

On the other hand, until the tablet market works out its purpose and finds a niche, I think it will continue to stagnate with fairly flat growth. 

It feels to me like a similar fate awaits smartwatches, until someone comes up with a compelling problem that the watch form factor solves, I think it will struggle to see big growth in the market.




Ideas

So this is just a quick note on some things that I am personally finding really interesting right now

Education 

as mentioned, I think this is going to be cracked soon, and maybe Khan academy will do it. Either way, I think whoever does it would need to be a "full stack" startup. I have thought about trying some things - like a GitHub type system for open-sourcing education materials and resources, creating open-standards for curriculum and educational texts etc - but they have always just been tools or things around the periphery. I don't think I have the resources right now to be thinking full stack!


Android first

Android is the most pervasive mobile OS (yes, there are some caveats about the stats, such as numbers coming from China, and the value of the customer compared to other iOS), and Google continue to widen their reach (recently purchasing Nest etc) I think we are going to seeing our first truly Android first apps. If Instagram was built today, would it be iOS first? Probably, but I think that landscape is changing. I think coupled with the following areas this could be a big one.  If I'm building a mobile app it's going to be Android first. Silicon valley is under-invested in Android - There is also growing appetite for it:



Smartphone as your social graph

I have mentioned this one a few times here. Smartphone usage is continuing to increase (even whilst tablet sales falter) and more and more existing mobile users across the world upgrade. Further to this, your smartphone is really where you social graph is. Your address book has your contacts in it, your phone number gives you a unique identifier, and as WhatsApp proved, it gives great power to mobile first startups to disrupt the social network incumbents. It could be argued that Google+ was never going to succeed to usurp Facebook as king of the social networks because people are lazy, and essentially creatures of habbit - if all your friends are on Facebook, why try to convince your entire network to switch to g+? But the smartphone takes away that power, as your network is on your device, not a particular platform.  Couple that with the fact that so many use their phones to double up as cameras it now means most of our photos/videos are also on the device.

Television

I was recently talking with some colleagues about the future of TV and I speculated that in 5-10 years we may see the end of scheduled television, and everything will be only on demand. This would leave some interesting questions/problems:

  • One big problem as I see it is the fragmentation of device software - if you are creating an on demand app, you need to think about Android, iOS, browsers, Xbox, PS, not to mention all the TV manufacturers that have their own software running on their web enabled TV. This means at the moment, if you buy a new web enabled TV or set top box, the on demand apps may not be available, and may not be consistent. I think this could be a good market for Android and wouldn't be surprised if they do make some bold moves in this area (yes, bolder than Chrome Cast) - I would think it would make sense for them to be linking up with TV manufacturers to as the de-facto TV OS (would benefit from android app eco system - even if it would mean a LOT more work for app developers to fix up for another range of screen sizes
  • Another interesting implication of such a switch would be would we see a decline in produced content. At the moment there is a lot of content created specifically for quieter times of the viewing schedule (mon-fri afternoons, early morning, etc) - what might be considered as "filler", but we might see a decline in this as consumers will have complete control of what they want to watch, and there won't be any watch it because its on mentality.
I think its an interesting areas where battles are really going strong, with big players in the content production/distribution space (Netflix/Amazon/YouTube) as well as Google/Apple etc taking on the incumbents in hardware.  I just today saw a link for a site called Glass that is dedicated to ongoing conversation about this topic.

Building a Twitter style autocomplete for Android

I have recently been working on an android app and found myself needing a Twitter style input box that allowed certain words to be looked up using an API driven autocomplete but also supporting freetext (if you have used the compose tweet input on android, like this - free text, but if you type @ then you get a user name autocomplete).



I google'd for a while, and stumbled through a few StackOverflow answers but none of there were 100% clear, and further more, just copy-pasting the code into a dummy project I was working in didn't work. So here is a break down of the what and how this works.

There are four main components:

The XML Layout: MultiAutoCompleteTextView


This is simple - just add the MultiAutoCompleteTextView just like you would any input. The only point of interest here is the "completionThreshold" - this is just the number of characters that have to be typed before auto-complete kicks in. We have set this to one char so it kicks in early.


We then just setup the auto-complete in our Activity onCreate

SetTokeniser: UsernameTokenizer

This is a custom class that implements the Tokenizer interface. This will be used by our autocomplete imput box to work out whether or not it should be displaying a dropdown menu. If you are using a static list for lookups (countries, fixed codes from your app, etc) then this is the only thing you really need to do - then you can just set the fields ArrayAdapter as the list of Strings etc and it will automatically kick in.

In our case, we are using the @ character to identify the start of pieces of text that should be lookedup and spaces to determine the end of the look up token.


The three methods are relatively straight forward - and will drive when your app presents the drop down:
  • terminateToken(CharSequence text) - this basically just provides a presentable version of our token with a proper terminator at the end (e.g. makes sure a trailing single space in this case)
  • findTokenStart(CharSequence text, int cursor) - Just finds the position of the start of the token. It does this by iterating backwards through the provided CharSequence (the text input in the input box) starting from the position of the cursor, which is just the position of the last character edited (this means if you go back and edit text in the middle of a block it still finds the correct token).  If no valid token start is found (e.g. we go backwards and we can't find a @ character) then the current position is returned - no dropdown is displayed.
  • findTokenEnd(CharSequence text, int cursor) - As above, but finds the end position. Iterates forward until a token terminator (in our case a space) or the end of the text is found

As long as you implement these to support your token identification pattern then you will get a dropdown appearing appropriately.


Adding a text changed listener

For ease of use on this one, I have just set the activity to implement the TextWatcher interface - the reason for this is just convenience - the implementation is going to handle calling our API asyncronously, so it is easier if it has the activity context.

There are three methods that need to be implemented - four our case there will be two no-op methods and just one implementation:


The method onTextChanged is implemented - unfortunately the tokenizer will only indicate to the application when to display the dropdown - it doesn't actually call the API, so we have to slightly repeat ourselves here in handling the API invocation.  In this method we need to again check for and find the relevant valid token in the input, and if a valid token found, then pass it to our API to lookup the dataset.

To help with that, I also added some additional methods to help check for the existence of a valid token (reading them should be self explanatory, but comments included inline)


In this case, as it was just an experiment, and I didn't actually have a user lookup API I have just used the LinkedIn skills API (this code also taken in part from a StackOverflow answer).

The Async task should also be straight forward, and can be implemented in whatever pattern you are using for Async calls - but the key point to note is how we are updating our dropdown list.


The API driven, multi-autocomplete/free text field should then be working as expected



Coming Soon..




New mobile-first product currently underway..

Flat Design (& Android)

"Flat" is currently a big design trend, with pretty much all the big players getting involved.  One of the earliest big-hitters in the field was an iOS app called LetterPress (incidentally, the designer behind this has recently been working on Facebook's "Paper" app - which is also a pretty nice experience)

http://www.atebits.com/letterpress/

The trend found a surprising champion in Microsoft with their Windows Metro look (Windows 8, Windows mobile, xbox), before Apple(iOS 7) later joined the party as Jonny Ives took responsibility for software design as well as hardware. Now many of the most popular sites are sporting a flat look (Google flattened its logo, twitter went flat, even NerdAbility.com is sporting a flat design).

Flat design is about being more minimalist and user-focused - it skips the fanfare of effects or lifelike details for apps/backgrounds/controls and favours simple, clean, crisp minimal interfaces. It's kind of the opposite to the skeumorphic approach - which is using lifelike textures/look&feels for things (the obvious examples being on iOS pre-7 where the contacts have graphics in the background that make it look like a leather address book, or the notes app that has a lined paper background etc).  It avoids fancy 3-d fonts and elements, avoids shading, shadowing, textures - and just uses simple colours, fonts, shapes to quickly convey meaning (see letterpress image above - no fancy rounded corners, fonts or textures - just simple block colours).


Flat Android Design

There is no reason why you can't design an Android app following flat trend, in fact lots already have - Thankfully, as a core part of the flat trend is simple, it is simple to build flat looking apps in no time at all.

Fonts

There isn't any hard and fast rule on fonts really - obviously it should be simple, clean and understandable - for this reason, clean, light san serif fonts have been a common font style to use. The most famous, as used by Microsoft, is Open-Sans - this is the font used across their Windows8 OS. It's popularity also boosted by the fact that it is freely available on Google Fonts, so has swept the web in a fairly big way.



Thankfully, as it happens, Android (since 3.0) has come with packaged with a lovely san-serif font called Roboto. The range of weights, especially the thin and bolder weights allow you to achieve similar aesthetics in line with common flat design, whilst presenting a professional, clean & simple typography.  The obvious disadvantage of using the font is as it's built into later Androids, it's fairly widely used.  Personally, I like to use it. I use the default Android font largely across my apps, and if I want to add a bit of character to a heading/title then I opt for the thinner version of the font.


Buttons

Buttons are an interesting one.  Whilst the flat trend is becoming more pervasive, there are still questions regarding buttons. Buttons have always been skeuomorphic by design - the shading and texture to show a raised/bevelled button (like a real life button that you might press) is classic skeumorphism, and whilst this is simple to switch to a 2-D, flat look&feel, there are still arguments as to whether you should do this - as the button look and feel communicates to the user that it is a button - it is so widely accepted a metaphor, people seem concerned that without the detail, people may not understand it is a button. How can they tell if something is a button or just a coloured block quote? (see this stackexchange question on the topic)

http://www.nngroup.com/articles/windows-8-disappointing-usability/

 Above is an example from Windows 8 controls - as pointed out on the StackExchange link, all of those icons are actually buttons, along with the "Change PC Settings" - That could be fairly confusing, and would be an example of how not to design flat buttons.

Personally, I like flat buttons - as long as you take care to design the page so that the buttons are clear, and the form/page obeys general good UI heirarchy - an example of a simple form I was creating for an app with simple flat buttons is below:


As you can see, designing forms/controls that obey standard UI heirarchy and normal metaphors then it is still incredibly simple and clear what are buttons are what aren't. (I know it doesn't look like a fancy form - there are other decorations elsewhere as well though!)


Colours

There are of course, no rules about colour - but there are trends. A simple google image search for flat colours will give you lots of palettes, and there are also lots of great free tools on the web for building palettes

http://mikehince.com/design/amazing-colour-resources-for-designers/


Adobe's Kuler being a great example (lets you build schemes as well as share them with the community and look at other schemes)



Android ORM - GreenDAO - Simplifying DB access in your app

I am currently working on a new Android app, and as usual, it requires a considerable amount of DB interaction.  I would say DB interaction isn't that difficult in Android - you can create a few simple classes to setup your schema and then DAO functions for the various domain objects that you want to map to the DB.

Simple.

Just a pain in the ass.

Coming from working on a variety of Java type ORMs (Hibernate et al), this is really just all boiler plate that is painful to write, so this time around I decided to look for an Android ORM. The first result in google was greenDAO, which claims to be being used on over 10million installed apps (AppBrain lists it as being used on Pinterest and Zynga apps), which seemed like pretty good reason to take a look.


So I started taking a look at the code on GitHub - the first thing I noticed was that it wasn't a traditional ORM that I expected, really it's more of a code generator rather than an ORM like Hibernate - I was expecting to just define some POJO entities, maybe marked up with annotations or config  that did all the magic - but what is actually going on is you have to create a "generator" project that defines your domain entities and then that produces several DAO and domain object classes that can be generated directly into your normal Android app.

Does generated code always suck?

I saw the words generator and alarm bells started to ring - I have worked with and on projects that generate code and it so often seems to have descended in to pain - often needing to slightly tweak the generated code, which then results in painful re-generation or just walking away from the generator altogether and being left with having to manually maintain generated code.

However, I had a look at the generated code and it was actually quite nice - not that different from if I had written it, and what swung it for me was the performance. I had briefly pondered building a lightweight ORM for Android more in the style of Hibernate (I love an annotation), but then I thought on the performance impact - reading annotations on POJOs at runtime - even if cached - the performance footprint was likely to be pretty big would suck for people with older/less powerful devices.


So actually, removing the pain of having to create all the DAO objects etc, whilst not having a prohibitive performance impact made this a pretty strong choice.


Let's get down to business, don't got no time to play around, what is this..

So lets have a look at how we generate the code - its actually relatively easily to programmatic-ly configure your entities for generation.





The above is an example of how you can configure two simple domain entities (which will map to a table - this is like defining a Hibernate @Entity POJO). In the above simplified, hypothetical design, we have two real domain entities "Email" and "People" - emails can be sent to multiple people, and people can recieve multiple emails.

As you can see, we define a very simple People entity. and then programatically add three columns - an ID, a name and an email address. Simple - and as you can see(or imagine) the API provides programatic constructs to configure not null, column types, etc.


All in all, so far it has been a good experience - It has removed a certain amount of the pain from developing the DAO/DB layer boiler plate stuff and let me concentrate on the important stuff about the app. However, one gripe I do have is that it doesn't currently support modelling of many-to-many relationships - the best you can do is create an entity to model what is effectively a join table, then have a one-to-many relationship from that to either side of your "real" many-to-many relationship.

Again, in the above example, we try manage the many-to-many relationship between people and emails (emails can have may people recipients, and people can be recipients to many emails). As mentioned - we have had to model this join explicitly with an EmailPeople entity, and then add the OneToMany relationship between People/Email to our new Join entity.  This is no real headache to do, but is undoubtedly going to be a performance hit - The underlying code will undoubtedly be being cleverly efficient in retrieving all the EmailPeople entities for a given email (assuming attempting to get all recipients to an email) - but from that list we then need an efficient way to load all the People enties linked to that list of EmailPeople entites.
 

Retiring my Apps (website)

I have decided this weekend to retire my Android app development website (if you haven't already checked it out, you can still find it here for a while). The site was only really to provide more information and a contact method for anyone interested in the apps (and as part of an online portfolio really) but as my focus has been on other things (amongst them being Flutterby) I decided it was time to retire the site.

The apps will still be available of course, from the Android market, and I also updated my photo FX app "The Cutting Room" to be free now (as well as previously open sourcing the Android image processing libraries).


A New App - Photo Effects and Filter Library



Recently I started looking at experimenting with the camera and manipulating images on the Android platform, and after a few weeks of experimenting I have finished and released a new app to the market that lets users capture still images and then apply a selection of filter/fx to their pictures.

It's a simple app, and is just a bit of fun for the user - the effects available are things like outline, neon, invert, b&w, pixelate, etc. There are more details about the app and some demo pictures on the page linked at the top of the blog entitled cutting room.

My experimentation started simply with playing about with some of the many Java image filter and effects libraries that are available such as Marvin and JH Labs. The Problem you find immediately when trying to link these up with your Android app is that the Android JRE does not include the core java AWT package. This limits the use of practically every image filtering library available as they all use java.awt.BufferedImage and the rest of the awt package.

Instead of the BufferedImage class, the Android platform provides its Bitmap class, and looking through the filter classes, it seemed like it should be fairly straight forward to port some of them over to Android, so I went with the Marvin library.

You can check out my final effects app the "Cutting Room" on the market, but I have also released the ported Marvin effects code on google code as open source, so feel free to check that out and use it for anything you feel fit!

I will post again soon walking through setting up an app to use the camera, so stay tuned for that.

Android & Twitter - OAuth Authentication Tutorial

I’ve seen a lot of questions about connecting Android apps with Twitter using OAuth and thought I would write up a walkthrough of how it can be done. The example will be done using Twitter4J which is a great library for connecting Java apps with Twitter and provides a simple interface to connect to the public Twitter Web Services.

First thing you will need to do is to register your new app (even though you haven’t made it yet!). Do this by heading to https://dev.twitter.com/apps/new (you will need an existing Twitter account sign up). You should complete the form with the relevant details for your app:


You should fill in your details for the application such as name, description, URL – but the only key things to remember to do here are as follows:

1) Make sure you select “Browser” as your application type – even though we are creating an app, we will authenticate using the browser and a callback URL.

2) Tick read & write permissions

Once you have registered you will be provided with a “Consumer Key” and a “Consumer Secret” – make note of these for later – we will need to include these in the app.


Now let’s get started with the app! I will assume for this tutorial that you are familiar with the basics of Android apps so won’t go into details about how to setup the UI and what an Activity or Application is.
The first thing we will do is create an Activity that will prompt the user to login to Twitter and authorize the app to connect to Twitter to make updates. Let’s start with the onCreate method:


@Override
public void onCreate(Bundle savedInstanceState) {
 System.setProperty("http.keepAlive", "false");
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main_oauth);
 
 //check for saved log in details..
 checkForSavedLogin();

 //set consumer and provider on teh Application service
 getConsumerProvider();
 
 //Define login button and listener
 buttonLogin = (Button)findViewById(R.id.ButtonLogin);
 buttonLogin.setOnClickListener(new OnClickListener() {  
  public void onClick(View v) {
   askOAuth();
  }
 });
}

The first line we set the http keepAlive property – this is important so the app manages the connection correctly without reseting. The next important thing is our call to the checkForSavedLogin() method – this is a method that checks whether the user has previously authorised the app to access twitter, in which case we can just proceed as usual to the default twitter timeline activity (we will have a look at that method next). Otherwise we just initialise the Consumer/Provider and store them in our Application class so they are available to all Activities throughout the application. Then finally we inflate the button on the page and set a listener to call the askOAuth() method on click.


Now let’s jump in to the checkForSavedLogin() to see whats going on there:

private void checkForSavedLogin() {
 // Get Access Token and persist it
 AccessToken a = getAccessToken();
 if (a==null) return; //if there are no credentials stored then return to usual activity

 // initialize Twitter4J
 twitter = new TwitterFactory().getInstance();
 twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
 twitter.setOAuthAccessToken(a);
 ((TwitterApplication)getApplication()).setTwitter(twitter);
 
 startFirstActivity();
 finish();
}



This method calls a method getAccessToken() – all this does is check in the user SharedPreferences to see whether we have stored the users AccessToken previously – if there is no token found it just returns, so the user is left on the authentication activity waiting input.

However, if a token is found, then we initialise Twitter4J Twitter object and store that in our Application class (again, so we can use it throughout the application).
Finally we call startFirstActivity(), which simply calls the default Twitter timeline activity we have and finishes the authentication activity as it is not needed.

So that is all good, if the user has previously authenticated then no probs – however, if no saved token is found the user still needs to authenticate so we need to handle the user action (remember we are calling the askOAuth() method from within our button listener).



Let’s have a look at that method – this is where the authentication is all done:

private void askOAuth() {
 try {
  consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
  provider = new DefaultOAuthProvider("http://twitter.com/oauth/request_token", "http://twitter.com/oauth/access_token", "http://twitter.com/oauth/authorize");
  String authUrl = provider.retrieveRequestToken(consumer, CALLBACK_URL);
  Toast.makeText(this, "Please authorize this app!", Toast.LENGTH_LONG).show();
  setConsumerProvider();
  startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
 } catch (Exception e) {
  Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
 }
}

First thing we do here is to initialise the Consumer and Provider objects – we are using the Commons OAuth Consumer/Provider (so you need to make sure you copy the following JARs in to your /assets/ directory and then add them to your build path: “signpost-commonshttp” and “signpost-core”).

You will see that the consumer is initialised using to static Strings CONSUMER_KEY and CONSUMER_SECRET – these need to be set to be the key and secret Twitter provided when you registered the app – you should make sure you keep these secret and not reveal them to people.

The provider is then just initialised using the relevant URLs that Twitter provides to authenticate againse.

Next, we call the retrieveRequestToken() method on the provider object, this takes two arguments: the consumer, and the CALLBACK_URL (another static string) we will come back to what this is later.

We then call startActivity with a new Intent using the authenticate URL – this is what will forward the user to the Twitter authentication service for them to securely login and authorize the app to make updates for them.



So now, we have a simple authentication activity, that if the user has never logged on before will forward them on to the Twitter OAuth service – next we need to handle the response from Twitter and if a successful response received, then store the Access Token for future use. This is all done in the onResume() method:

@Override
protected void onResume() {
 super.onResume();
 if (this.getIntent()!=null && this.getIntent().getData()!=null){
  Uri uri = this.getIntent().getData();
  if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
   String verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
   try {
    // this will populate token and token_secret in consumer
    provider.retrieveAccessToken(consumer, verifier);

    // Get Access Token and persist it
    AccessToken a = new AccessToken(consumer.getToken(), consumer.getTokenSecret());
    storeAccessToken(a);

    // initialize Twitter4J
    twitter = new TwitterFactory().getInstance();
    twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
    twitter.setOAuthAccessToken(a);
    ((TwitterApplication)getApplication()).setTwitter(twitter);
    //Log.e("Login", "Twitter Initialised");
    
    startFirstActivity();

   } catch (Exception e) {
    //Log.e(APP, e.getMessage());
    e.printStackTrace();
    Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
   }
  }
 }
}


First thing, the method checks that the intent that has called the onResume is the expected intent, and then pulls out the verifying string from the callback URI – it then uses this string to retrieve the access token. Once we have called the retrieveAccessToken() method, we can initialise an AccessToken and store it. Next we initialise the Twitter4J object with the CONSUMER_KEY and SECRET again and then set the Access Token – once this has all been setup we just start the first activity as normal.
Once the user has authenticated they will be forwarded to the their friends timeline!

Now, the only thing remaining, is that we need to tell the app that once Twitter has finished authenticating that it needs to return to our Authentication Activity to call the above onResume method, or else it won’t be able to continue. To do this, Twitter will attempt to use the CALLBACK_URL we saw earlier. If you remember, when we requested the token from Twitter we passed in the CALLBACK_URL. I have previously defined this as follows:

private String CALLBACK_URL =           "callback://tweeter";

The name of the callback is up to you (I have named it “tweeter”), what is important is that this matches the callback you define in your Manifest XML. For the welcome activity (our Authentication activity) it needs to be defined as follows:


 
  
  
 
 
  
  
  
  
 



As you can see, we have defined an intent-filter with a scheme called “callback” and we provide the host name as “tweeter” – matching that used to call the Twitter service.

And thats it! The user has been authenticated and returned to our application correctly, so it can now continue to read timelines, post tweets, retweet, etc.



The complete source code of the application is available here (NOW ON GITHUB!), please note that I have removed my own CONSUMER_KEY/SECRET details, so to make this work you will need to register your app and populate with your own details to see it work in your emulator/device.

Getting Started - A Complete Android App walkthrough for Beginners (Part 2)

This is part 2 of a walkthrough of one of my first ever Android app, that happened to get a little bit of love in the android market, and for which the ENTIRE(!!) source code of the application is available to you good people to do whatever you want with.. see part 1 for more details of the app, what happened and the first steps in getting started!

So far, we have created a simple Activity class, designed a layout with several buttons and then implemented an onClickListener within our Activity class to handle the required actions for all of our buttons. The remaining Activities are all fairly straight forward, and work in a similar fashion: the RulesActivity is just a simple activity what has a block of text with a brief description of the game; the SettingsActivity is a simple activity that has three radio buttons which allows the user to select the difficulty; the QuestionsActivity just displays a question and then a selection of multiple choice answers.

If you are not familiar with Activities then you can open up those other classes and see exactly what is going on, they are all pretty similar but each have slight nuances or differences in their components and actions.

At the moment the application is pretty simple – there is a basic welcome screen with some buttons, and once you start the game you get taken through the QuestionsActivity several times, refreshing with different questions until you have answered all the questions, and then at the end it displays a simple graphic based on your accumulated score. Easy right?!

Really, the only big gap in what is going on is the DB – all the questions need to be stored in the DB on the client device, and then that data needs to be accessed, so we basically need a DAO type class.

In this app, we have a single DBHelper class – you may want to wrap this with a service class, to allow better separation of layers and decreased coupling etc, but for the sake of this app, lets just jump into the DBHelper. To access the DB on Android you need to have your class extend SQLLiteOpenHelper, now lets walk through the code required

private static String DB_PATH = "/data/data/com.tmm.android.chuck/databases/";
private static String DB_NAME = "questionsDb";
private SQLiteDatabase myDataBase; 
private final Context myContext;

First of all we define some simple class member variables. The DB_PATH will be used later to access our file that contains all our questions in it, the DB_NAME is just a name of choice to reference the DB.

public DBHelper(Context context) {
 super(context, DB_NAME, null, 1);
 this.myContext = context;
} 

You have to make sure you override the constructor, as this needs to initialise the context and DB before starting.

Next we have the createDatabase method – this one is quite straight forward:

public void createDataBase() throws IOException{

 boolean dbExist = checkDataBase();
 if(!dbExist)
 {
  this.getReadableDatabase();
  try {
   copyDataBase(); 
  } catch (IOException e) {
   throw new Error("Error copying database");
  }
 }
}


As you can see, it simply checks if the DB already exists, if it doesn’t (in which case its the first time that the app has been launched on this device) then it calls the copyDataBase() method:

private void copyDataBase() throws IOException{

 InputStream myInput = myContext.getAssets().open(DB_NAME);

 String outFileName = DB_PATH + DB_NAME;

 OutputStream myOutput = new FileOutputStream(outFileName);

 byte[] buffer = new byte[1024];
 int length;
 while ((length = myInput.read(buffer))>0){
  myOutput.write(buffer, 0, length);
 }

 //Close the streams
 myOutput.flush();
 myOutput.close();
 myInput.close();
}

Again, this is pretty straight forward – it just opens an Input stream to read the file (our questions file that we have saved in the /assets/ directory) and then writes it to the output stream which has been set up to be our DB Path/Name. Easy right?

So now we pretty much have our DBHelper class that checks for an existing DB, if its found then it opens a connection, if its not then it loads the data (our question set) in for the first time.

Now, the only remaining thing that our helper needs to do is to be able to access the data so we can select questions to show the user. So let’s look at how we add some DAO access methods. What I have done here is create a simple method to return a (random) question set:

public List getQuestionSet(int difficulty, int numQ){
 List questionSet = new ArrayList();

Cursor c = myDataBase.rawQuery("SELECT * FROM QUESTIONS WHERE DIFFICULTY=" + difficulty +
   " ORDER BY RANDOM() LIMIT " + numQ, null);
 
while (c.moveToNext()){
  Question q = new Question();
  q.setQuestion(c.getString(1));
  q.setAnswer(c.getString(2));
  q.setOption1(c.getString(3));
  q.setOption2(c.getString(4));
  q.setOption3(c.getString(5));
  q.setRating(difficulty);
  questionSet.add(q);
 }
 return questionSet;
}

Here, I am modelling the questions in a pre-created “Question” class – this just has the necessary member variables so I can handle the questions more easily than having to try and deal with DB cursors throughout the code. In the above method we just call a pure SQL statement, and then iterate through the cursor to populate my Question ArrayList.

And thats it! There are some other Activity classes and helper classes running doing small things throughout the app, but the core features are covered, so feel free to have a look around the code, edit it, change the design and just generally have fun.

Getting Started - A Complete Android App walkthrough for Beginners (Part 1)

About a year ago I released my first app on to the Android market. I had developed the market primarily as a learning tool, and at the end decided that putting it on the market would be a good step to understand the process and get some feedback.
The application was a simple quiz app based on the popular NBC series Chuck, I released it for free (no-ads) and no real advertising other than one or two target tweets. The app currently has about 4,000 – 5,000 downloads with a 4 star rating – both of which it achieved pretty quickly in the first month or two.



DISCLAIMER: I believe this to be purely down to the fact that at the time there weren’t really any other Chuck related apps, and it has a nerd-ish, cult like following, so I think the rating and popularity is more of a reflection on the show’s popularity than the quality of the app!


Anyway, I thought it might be interesting/helpful to release the source code here and walkthrough the different aspects of the code in a tutorial “my first app” kind of way.

I won’t go in to the setting up Eclipse/Android plug-ins stuff here, so will assume familiarity with getting around the IDE.


Android Directory Structure
Creating a new Android project in Eclipse (using the Android plug-ins) creates the required project structure automatically for you. Lets have a look at that now:


Src : as you would expect, this is the main java source directory, so this is where all your source code lives

Gen: this is the generated code that Eclipse handles for you – the files in here will be generated from your config. You needn’t really worry about what happens in here as Eclipse takes care of it for you

Assets: this can be used to contain any resources or libraries you want to bundle with the app – such as third party jars and data sets (you will see later we use this directory to store the data that we will load to populate all the questions in the DB when the app is first launched on a new device)

Res: this is where the configuration for the layout/UI aspects live:
- Drawable – keep you image files in here (.png/jpg/etc)
- Layout – this is where you keep the xml config for UI layout
- Values – this is where you keep the config with application code, such as application name or set text. This means you can easily change text through out the application without having to change hardcoded strings in the java code and re-compile


Getting Started
Ok, lets get started – the first thing we need is a welcome screen that is displayed when a user first launches the app. In Android, a screen is modelled by an “Activity” class, so to create our welcome screen we need to extend Activity.

public class SplashActivity extends Activity implements OnClickListener{

 @Override
 public void onCreate(Bundle savedInstanceState) {

Every class that overrides the Activity class must implement the onCreate() method – this is called when the activity is launched. As our welcome screen will just be a simple screen with a few buttons on it (play, rules, exit) we don’t need to do much at this point other than set up the buttons to have a listener so we know when one of them is pressed. For convenience here, we will set our current activity class to implement “OnClickListener” – this means we can define the onClick() method directly in our activity to handle the button events.

@Override
 public void onClick(View v) {
  Intent i; 
  switch (v.getId()){
  case R.id.playBtn :
   List questions = getQuestionSetFromDb();

   GamePlay c = new GamePlay();
   c.setQuestions(questions);
   c.setNumRounds(getNumQuestions());
   ((ChuckApplication)getApplication()).setCurrentGame(c);  

   //Start Game Now.. //
   i = new Intent(this, QuestionActivity.class);
   startActivityForResult(i, Constants.PLAYBUTTON);
   break;
   
  case R.id.rulesBtn :
   i = new Intent(this, RulesActivity.class);
   startActivityForResult(i, Constants.RULESBUTTON);
   break;
   
  case R.id.settingsBtn :
   i = new Intent(this, SettingsActivity.class);
   startActivityForResult(i, Constants.SETTINGSBUTTON);
   break;
   
  case R.id.exitBtn :
   finish();
   break;
  }
 }

As you can see, we have one single method that handles any button press, and we manage this with a switch statement checking the id of the view (we will go into this later). Mostly, the cases are simple, “exit” finishes the application whilst “rules” and “settings” have code like this:

i = new Intent(this, RulesActivity.class);
startActivityForResult(i, Constants.RULESBUTTON);

Intents are objects in Android that are used to communicate between activities, and as you can probably spot from the above, this simply creates a new Intent and then uses it to start another Activity class, in this case, our RulesActivity class.

The “Play” case is slightly more complicated – as this needs to initialise the game and load the questions to be used from the DB. Once it has done this, it loads the information in to our “Application” class (we will cover this later also) and then just kicks of the QuestionsActivity with a new Intent as per above.

So that is our welcome page pretty much done, we have a single screen that has a few buttons and we have setup listeners to perform appropriate actions on pressing them. The only remaining issue is the layout of the screen.


Activity Design

In the onCreate() method of our Activity you will notice the second line is

setContentView(R.layout.welcome);

This call tells Android which layout xml file should be used to configure the design – to find the relevant file is quite intuitive, its simply going to be located at /layout/welcome.xml



There are several layouts available to use, each of which are applicable in different circumstances, but as we are just going to have a straight list of buttons, we will use the simple “LinearLayout”. You can nest layouts, as you will see in this example, but lets walk through some of the config options we are using for our layout:

android:orientation="vertical" – This defines our layout as vertical, so new elements will be added on a new row below (if it were horizontal it would add as a new column)

android:layout_width="fill_parent" – this tells the activity to fill the whole width of the screen with the contents

android:layout_height="fill_parent" – this tells the activity to fill the whole width of the screen with the contents

android:gravity="center_horizontal" – this centers all elements that are contained in this layout

android:background="@drawable/background – this defines a background image to use for the activity (this image should exist at /drawable/background.png)


Now, if we look inside the layout you will see some simple components. The first one being a simple ImageView, which points to an image that we want to use as a header. The following elements are the buttons – you will notice that the ID of each button corresponds to the onCreate() method of our Activity where we inflate the button to set the onClickListener.
If you press the “Graphical Layout” tab in eclipse, you will see what the welcome screen will look like.




Ok, so we have our welcome Activty, we have designed a nice UI to control the app and have an onClick handler - the next part will cover intergrating with the DB to pull out the questions and then we are all there!


Grab complete source code for the project here

Getting Started - Best Books to learn Android

I wanted to recommend a couple of great books to get people started learning Android (of course, you could just skip the books and just use some of my tutorials including source code ;)



Hello, Android
This is a nice introduction to the Android platform - walking through from simple applications (as you may guess from the title!) through to some more complex topics such as working with Android's built in SQLite DB and OpenGl Graphics.
Note though that the book isnt a Java book (as none of these here are), and whilst its an introduction to Android, its not an introduction to the wider Java language structure/syntax - so will assume an understanding of the background.



Beginning Android Games
A great book to get started with Android game development! One of the nice things about this book is that it a more hollistic walkthrough of mobile game development and covers more general topics and issues for the area, whilst also providing specific Android examples to try out, it should give you a firm grounding in Android Game development.
The one thing to note that whilst this book does give you an excellent base in game development, it doesn't cover any of the great libraries currently existing for game development such as AndEng, libGDX, Rokon etc


Pro Android 2
This book is actually in its third edition now, but I only have the second edition, so I will link that here - although edition 3 is probably also a good shout.
First thing to mention, don't be fooled by the name! Whilst it descibes itself as Pro Android, it is still pretty suitable for a beginner (I found it was anyway, as long as you know Java, XML, etc) - and actually if you are looking for a "Pro" book this may not be the one for you as it doesn't cover all the topics you may expect for a pro book - such as use of the accelerometer and physics engines. That said, it does provide a solid covering of core topics needed for Android development right through from UI/Menu design through to also covering 2+3/D graphics.

Android Twitter Reader

Following on from the RSS Reader, some time last year I was investigating using Twitter in some of my apps, so I put together this simple Twitter reader (it only reads tweets from a given user - it doesnt allow posting etc)




For the most it is the same as the RSS Reader in terms of laying out the Android Lists and the layout.xml, so I won't go over that, I will just go through the Twitter integration.

The first step is to retrieve all the tweets, for this I am using the very useful Twitter4J Java library that simply wraps the Twitter API with a Java API

Twitter twitter = new TwitterFactory().getInstance();
  List statuses = new ArrayList();
     try {
   statuses = twitter.getUserTimeline(screenName);
  } catch (TwitterException e) {
   Log.e("Twitter", "Error logging in to Twitter");
   Log.e("Twitter", e.getMessage());
  }


Once you have the list of latest tweets, I convert them in to JSON so my listAdapter can process them more easily:

ArrayList JOBS = new ArrayList();
  try {
   if (statuses.size()>0){
    for (Status s : statuses){
     String avatar = "https://" + s.getUser().getProfileImageURL().getHost() + s.getUser().getProfileImageURL().getPath();
     JSONObject object = new JSONObject();
     object.put("tweet", s.getText());
     String timePosted = Utility.getDateDifference(s.getCreatedAt());
     object.put("tweetDate", timePosted);
     object.put("author", s.getUser().getName());
     object.put("avatar", avatar);
     object.put("userObj", s.getUser());
     object.put("tweetId", s.getId());
     
     JOBS.add(object); 
    }
   }else{
    JSONObject object = new JSONObject();
    object.put("tweet", "You have not logged in yet! Please log on to view latest tweets");
    object.put("author", "");
    JOBS.add(object);
   }

  } catch (JSONException e1) {
   Log.e("JSON", "There was an error creating the JSONObject", e1);
  }


And thats pretty much that! the listAdapter just pulls the information out of the JSON objects as per above and displays as necessary. The only other thing I will show is a little Date util class to make the date posted a little more fun:

public static String getDateDifference(Date thenDate){
        Calendar now = Calendar.getInstance();
        Calendar then = Calendar.getInstance();
        now.setTime(new Date());
        then.setTime(thenDate);

        
        // Get the represented date in milliseconds
        long nowMs = now.getTimeInMillis();
        long thenMs = then.getTimeInMillis();
        
        // Calculate difference in milliseconds
        long diff = nowMs - thenMs;
        
        // Calculate difference in seconds
        long diffMinutes = diff / (60 * 1000);
        long diffHours = diff / (60 * 60 * 1000);
        long diffDays = diff / (24 * 60 * 60 * 1000);

  if (diffMinutes<60){
   if (diffMinutes==1)
    return diffMinutes + " minute ago";
   else
    return diffMinutes + " minutes ago";
  } else if (diffHours<24){
   if (diffHours==1)
    return diffHours + " hour ago";
   else
    return diffHours + " hours ago";
  }else if (diffDays<30){
   if (diffDays==1)
    return diffDays + " day ago";
   else
    return diffDays + " days ago";
  }else {
   return "a long time ago..";
  }
 }