Thursday, 28 July 2011
Android Developers Blog: New Tools For Managing Screen Sizes
Very good and interesting read:
Android Developers Blog: New Tools For Managing Screen Sizes
Monday, 25 July 2011
Bypassing Proxies by setting Maven POM properties
After running into major issues this morning when trying to test a 3rd party SOAP based webservice integration with a "Connection Refused" exception being thrown I thought I'd share the issue and solution.
Recently a new proxy server has been setup with all back-office network traffic now going through it, this was stopping my local sandbox from hitting the required endpoint.
In order to ressolve this you can simply add some addiitonal system properties to your pom.xml file so Java can bybass the internal proxy. Replace {port} and {server} with your proxy settings and it should work straight away.
See: http://info4tech.wordpress.com/2007/05/04/java-http-proxy-settings/ for further settings if required.
Recently a new proxy server has been setup with all back-office network traffic now going through it, this was stopping my local sandbox from hitting the required endpoint.
In order to ressolve this you can simply add some addiitonal system properties to your pom.xml file so Java can bybass the internal proxy. Replace {port} and {server} with your proxy settings and it should work straight away.
See: http://info4tech.wordpress.com/2007/05/04/java-http-proxy-settings/ for further settings if required.
http.proxyPort {port} http.proxyHost {server}
Saturday, 9 July 2011
ORMLite and Android a good Companion
Persistence with Android
When creating Android applications there are many ways for you to store data, each fit for its own purpose. Below is a quick break down of the 5 main and recommended ways for applications to persist data with Android. More information can be found on the developers guide.
As part of this guide I'm going to demonstrate how ORMLite can be used to aid and ease the development of Android applications and make storing data much easier than interfacing directly with Androids inbuilt SqlLite database.
About a month ago I stumbled across a object relationship mapping (ORM) library which supports Android. After a little investigation, porting an existing application and using it from scratch for a new application I am currently developing I deem ORMLite and Android to be a great companionship. As part of this post I will try and show you how easy it can be to use ORMLite for Android, plus demonstrating how I use the library and how it has naturally fit in with my current development practices and patterns.
When creating Android applications there are many ways for you to store data, each fit for its own purpose. Below is a quick break down of the 5 main and recommended ways for applications to persist data with Android. More information can be found on the developers guide.
- Shared Preferences - Ideal for application settings and small chucks of data which can be used globally within your application. Options include booleans, floats, ints, longs, and strings all which are stored as key-value pairs.
- Internal Storage - Ideal for storing application cache data, this medium is private to your application.
- External Storage - Store public data on either removable storage media (such as an SD card) or an internal (non-removable) storage. Used for storing pictures, ring tones, music etc.
- SQLite Databases - Store structured data in a private database. The database is private to the application and consists of standard CRUD options.
- Network Connection - Store data on the web with your own network server. Can be used for all purposes, will be familiarly to most Java developers, must have an available data connection for this to work. Classes with the following packages can be used, java.net.* or android.net.*
As part of this guide I'm going to demonstrate how ORMLite can be used to aid and ease the development of Android applications and make storing data much easier than interfacing directly with Androids inbuilt SqlLite database.
About a month ago I stumbled across a object relationship mapping (ORM) library which supports Android. After a little investigation, porting an existing application and using it from scratch for a new application I am currently developing I deem ORMLite and Android to be a great companionship. As part of this post I will try and show you how easy it can be to use ORMLite for Android, plus demonstrating how I use the library and how it has naturally fit in with my current development practices and patterns.
Alternatives
There are afew alternatives available to using ORMLite two of which can be seen below. The other two projects are reasonably new and since the Android ORM space is still in early days I'm sure new libraries will emerge. I prefer the syntax when using ORMLite plus find it more intuitive to use and develop with. I also like the fact ORMLite is a multi functional library which supports several databases.
There are afew alternatives available to using ORMLite two of which can be seen below. The other two projects are reasonably new and since the Android ORM space is still in early days I'm sure new libraries will emerge. I prefer the syntax when using ORMLite plus find it more intuitive to use and develop with. I also like the fact ORMLite is a multi functional library which supports several databases.
I am yet to do any performance based analysis on either ORMLite or any alternatives. At a later date I may re-create the example from this post in all three and try come up with some simple performance based analysis on the three ORM libraries mentioned.
Example Project
For the purpose of this example I will be creating a small Android Application which contains a one-to-many relational table structure which you will be able to view, add, edit and delete entries. All source files can be found at my Github account here.
1) Simply create a new Android project with the standard eclipse wizard. I've called mine DemoORMLite with the main activity called DemoORMLiteActivity.
Creating your Database Helper
You will need to create a DatabaseHelper to allow ORMLite to create and manage your database. You can extend OrmLiteSqliteOpenHelper.class which will allow ORMLite to take over management. Simply create your table structure using helper methods such as the ones highlighted below. I also use this as an opportunity to expose my Dao's.
Creating your repository
The repository layer wraps all ORMLite calls hiding any exceptions and code relating to all database operations. This means when I use this in my Android Activities I will not have to deal with try/catch exceptions and can easily standardise what happens on these situations. Adding a further layer to your code may not always be suitable especially when using resource limited devices such as Mobile phones but I don't expect the impact to out way the code cleanliness/abstraction and ease of development when accessing a database via this means.
Why must I extend another Class?
The relationship consists of one PERSON has many APP's.
Setting up your project1) Simply create a new Android project with the standard eclipse wizard. I've called mine DemoORMLite with the main activity called DemoORMLiteActivity.
2) Next download the packages ormlite-android-4.23.jar and ormlite-core-4.23.jar and add these to the classpath of your Android project. If your using Maven these packages appear to be accessible so add them to your pom as normal. You are now ready to use ORMLite.
Creating your domain classes
Below are the two domain classes I have created, Person.class and App.class. As ORMLite is annotation driven you simply annotate your classes with the required options, setting field constraints as required. Next annotate your class defining the table name. In this example I have followed the standard bean convention having private fields and public getter and setter methods, this is optional.
@DatabaseTable(tableName = "persons") public class Person { @DatabaseField(generatedId = true) private int id; @DatabaseField(canBeNull = true) private String name; @ForeignCollectionField private ForeignCollectionapps; // Getters and setters are also present but not show in this demo public Person() { // all persisted classes must define a no-arg constructor with at least package visibility } }
@DatabaseTable(tableName = "apps") public class App { @DatabaseField(generatedId = true) private int id; @DatabaseField(canBeNull = true) private String name; @DatabaseField(foreign = true, foreignAutoRefresh = true, columnName = "person_id") private Person person; // Getters and setters are also present but not show in this demo public App() { // all persisted classes must define a no-arg constructor with at least package visibility } }
Creating your Database Helper
You will need to create a DatabaseHelper to allow ORMLite to create and manage your database. You can extend OrmLiteSqliteOpenHelper.class which will allow ORMLite to take over management. Simply create your table structure using helper methods such as the ones highlighted below. I also use this as an opportunity to expose my Dao's.
// Should be called inside the onCreate method TableUtils.createTable(connectionSource, App.class); TableUtils.createTable(connectionSource, Person.class); // Should be called inside the onUpgrade method TableUtils.dropTable(connectionSource, App.class, true); TableUtils.dropTable(connectionSource, Person.class, true); // Exposing the Dao for App CRUD operations public DaogetAppDao() throws SQLException { if (this.appDao == null) { this.appDao = getDao(App.class); } return this.appDao; }
Creating your repository
The repository layer wraps all ORMLite calls hiding any exceptions and code relating to all database operations. This means when I use this in my Android Activities I will not have to deal with try/catch exceptions and can easily standardise what happens on these situations. Adding a further layer to your code may not always be suitable especially when using resource limited devices such as Mobile phones but I don't expect the impact to out way the code cleanliness/abstraction and ease of development when accessing a database via this means.
// An example of a delete method on my repository public void deletePerson(final Person person) { try { final ForeignCollectionapps = person.getApps(); for (final App app : apps) { this.appDao.delete(app); } this.personDao.delete(person); } catch (final SQLException e) { e.printStackTrace(); } }
Using with your Activity
Your activity will need to extend an ORMLite activity wrapper to enable your application to use the library (See below for a further explanation). Once you have extended the correct activity it can be treated exactly as the original parent class. Below is a sample of the DemoORMLiteActivity class onCreate method I created and how I use the repository mentioned before.
@Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create a new repo for use inside this activity this.demoRepository = new DemoRepository(getHelper()); // Get all people, I use this to then create a simple list view and array adaptor. this.persons = this.demoRepository.getPersons(); // Additional Android specific code in here }
Why must I extend another Class?
Coming from a main enterprise Java background I'm used to simply using @Autowired or @Inject to obtain my Services and DAO's and letting my container deal with finding and setting the required fields etc. So the idea of extending a class just to be able to access my database layer is something I don't see too often but it isn't doing anything complicated and simply exposing ORMLite to the most common Android components. Check out the sourcecode for the four base classes (OrmLiteBaseActivity, OrmLiteBaseListActivity, OrmLiteBaseService, OrmLiteBaseTabActivity) and you will find all set up and exposeure of a DAO layer which you can use inside your main Android Classes plus it will deal with opening and closing of your DB connections. I am yet to run into a scenario where the base classes don't fit my need, and if so you can always create you own.
Conclusion
I have not gone in to great depth in this demo but simply tried to show how easy it can be to use ORMLIte with Android. Previously using Androids inbuilt DB classes has proven to me to time consuming, clunky and error prone, plus the code is never as clean as when using this library. All sources can be grabbed from my GitHub account here, the example application is a simple demonstration of some CRUD options inside a very simple Android application. In total the application took no more than 1hour to create. When using the application long press each row to get a list of options available to each entry and single click each row to get a list of applications each person has.
All thoughts, comments and opinions are always welcome.
James
Conclusion
I have not gone in to great depth in this demo but simply tried to show how easy it can be to use ORMLIte with Android. Previously using Androids inbuilt DB classes has proven to me to time consuming, clunky and error prone, plus the code is never as clean as when using this library. All sources can be grabbed from my GitHub account here, the example application is a simple demonstration of some CRUD options inside a very simple Android application. In total the application took no more than 1hour to create. When using the application long press each row to get a list of options available to each entry and single click each row to get a list of applications each person has.
All thoughts, comments and opinions are always welcome.
James
Tuesday, 28 June 2011
Latest Ramblings
After getting back from am amazing holiday travelling around Brazil I've been yearning to get stuck in to some code after a good 3 three weeks plus off.
I've finally got round to starting my latest Android application, and have been investigating some various methods and libraries for use in my persistence layer.
One of the libraries I've been looking into has been ORMLite. A simple ORM library which I don't think is specifically built for Android but has good support. It tries to follow the KISS principle which I believe will fit nicely in to the resource limited scope which many Android supported devices have. Previously I have ending up making simple wrapper classes which I have used as a form of object to DB mapping but then in the end still actually writing my own SQLLite queries and handling connect scope etc. After trialling it this weekend and creating a few simple relational classes it seems to fit my purpose well. It doesn't have all the bells and whistles of a big ORM library such as Hibernate
but it makes the creation and query of my SQLLite tables much easier.
One good thing about using a ORM technology is that when using it, it quickly developed itself it to a very familiar structure which I have seen in many projects forming a simple Repository layer. Coming from a enterprise background, usually working on large scale J2EE
, JDBC
and/or Hibernate
based projects, the class structure and layout all feels good and usable, a problem which I have had when directly interfacing with SQLLite via the inbuilt Android libraries. After a few more weekends hacking away I'll aim to get a simple demonstration of ORMLite's capabilities and show how I use it plus any issues and aids I have develop when using the library.
I've finally got round to starting my latest Android application, and have been investigating some various methods and libraries for use in my persistence layer.
One of the libraries I've been looking into has been ORMLite. A simple ORM library which I don't think is specifically built for Android but has good support. It tries to follow the KISS principle which I believe will fit nicely in to the resource limited scope which many Android supported devices have. Previously I have ending up making simple wrapper classes which I have used as a form of object to DB mapping but then in the end still actually writing my own SQLLite queries and handling connect scope etc. After trialling it this weekend and creating a few simple relational classes it seems to fit my purpose well. It doesn't have all the bells and whistles of a big ORM library such as Hibernate
One good thing about using a ORM technology is that when using it, it quickly developed itself it to a very familiar structure which I have seen in many projects forming a simple Repository layer. Coming from a enterprise background, usually working on large scale J2EE
Saturday, 28 May 2011
To Scrum or Not To Scrum?
The company where I work we have always practiced a version of Scrum and tried to be as agile as possible, all being resource, time and money prohibiting. Everything I mention in this post I am or have been guilty of at some point.
Friday I hosted a retrospective with the rest of the development team like we have many times before and tried to come up with some areas of improvement as well as bringing all issue to the forefront, plus a bit of venting from everyone. Some of the main points that had been raised are points below:
- Last minute requirements from the business forcing late code changes and rushed releases.
- Lacking of a product owner/area specialist who was willing to take responsibility for the product being released.
- Scope to woolly and acceptance criteria being defined by development post implementation.
- A constant small stream of tasks which had been deemed maintenance tasks but had really been small features or tweaks to existing code bases of products.
After some debate and some insightful questions the conclusion all boiled down to development work starting to early. This isn't the first time and won’t be the last time that this conclusion will be drawn. Developers weren't strong enough to kick-back tasks at the business when no requirements had been gathered, and the scope so woolly it left it to the imagination of the developers. Time wasted in meetings post implementation trying to define A/C and testable characteristics, basically constantly chasing our tails trying to fill in the gaps we had previously missed out.
To Scrum or Not To Scrum
This leads me on the next discussion we had: Why do we practice Scrum? Do we actually practice Scrum anymore? What alternatives are there? Ever since I joined the team we have been practising a form of Scrum within the development team and things worked well. Tasks would been defined early enough, 90% of the time we stuck to a standard fortnightly release cycle, most of the time we have Product Owners, most of the time we have Stakeholders, a Scrum Master, try to release every sprint, the business would define the next sprints work and we would estimate and plan. All had been working well (with the minor hic-up) up until the last few months when development changed.
The business started making decisions faster, being more volatile and reactive, this could be due to the financial/industry pressures within the company and or a greater focus on pushing through new products and services which obviously will hopefully be paying my wages in the future. As the business had become more reactive and proactive in the current market climate the development team had not really thought about how the changes will affect the team and development process. We did not have the mind set to deal with the new changes especially the speed and or the volume. We still are thinking in a very iterative and almost waterfall model (it hurts to say it), letting each specialism within the team take responsibility for that function only, i.e. developers just being developers, testers just testing and leaving our business analyst to just be doing the analysis. This is ineffective and we all needed a little reality check!! WE ARE AGILE, we are proud to AGILE and yet we had failed with one of its most fundamental features. I don't think this had been done intentionally and I think this slip up is a recent problem and not one which had been causing major problems previously. So after much more discussion we came to the conclusion that Scrum isn’t really what we practice and if it is, it is being bent and squeezed to fit our current development cycles and current needs.
I think one of the biggest problems had been the team struggling with the change and the constant rush of new feature requests which had been splitting the team up (and focus), each pair working on varying different tasks but yet the sprint still being classed and termed like it was a standard sprint.
We were not doing the project work originally planned out and the project work we had been doing was falling way behind due to features and changes which the business had been making at a much greater rate. Our team resource had been reduced and not only are we working on a single large several week project but also on many small tasks on different platforms, different projects and other smaller projects being thrown in a sprint half way through. We had not planned for this, our code base is all messed up, and releases had failed. Larger features being coded against the branch as the trunk is un-releasable due to the original large scale project we had estimated would take several releases. We had been doing project based work for some time now, focusing on larger scale projects defined from the business, incrementally pushing out new features with an overall common goal which had been loosely defined. New features/products were now being elbowed into this and simply placed under the same umbrella of our main goal, even though the goal posts had moved. Trying to please all and trying to be as agile as possible we had simply accepted these changes and not taken into account how it would affect the way we had been happily working for some time. Scrum and ourselves had failed to manage the current working conditions, the business at present did not really need a team who used Scrum, it was too ridged and we had been practicing a very fluid ad-hoc style and it doesn’t fit anymore.
What’s next?
Kanban or Scrum-ban had been raised as a possible alternative to Scrum and is possibly a much better alternative way for us to manage the ever changing needs of the business. Scrum-ban sounds like it would be a great place to start, “Scrum-ban is especially suited for maintenance projects or (system) projects with frequent and unexpected user stories or programming errors. In such cases the time-limited sprints of the Scrum model are of no appreciable use” – wiki. Making the move from Scrum to pure Kanban may not have the same benefit and the change may be too great and too quick for the first step. Changing from Scrum to Scrum-ban hopefully will be beneficial to the development team and if all fails and we revert to the old pure Scrum methodologies then we only land back at where we are now. We need to ensure we retrospectively follow up each change. Making adjustments if required will hopefully mean the move will be a successful one.
As development we have work to do, improving communication and being more agile all around would make our reactivity much better and reducing the problems mentioned earlier. We had improvements to make in our source control management, having three streams not just a trunk and branch, but also a development branch which would improve flexibility of our code base and not render it redundant if features have been half finished or stories had been dropped from the sprint. Team functions need to be less isolated, developers can help out if testers are behind and testers can pair with developers on particular tasks to ensure test coverage is complete.
All in all I looking forward to practicing in a slightly alternative management style and it may just be the making of our team. I’ll report back on the changes made, how they fit in to our development team and the successfulness. Comments and feedback always welcome.
James.
Sunday, 15 May 2011
Groovy, Apache Batik and a little syntactical sugar speeds up Android development
As I read more and more of
Android in Action

and further delve into the world of mobile development, one of the newer concepts I have come across is how to scale android applications to various different sizes of screen, hardware and resolutions.Google have good documentation in this subject area and have an entire section of the developer portal dedicated to this but this doesn't mean that trying to ad hear to them isn't a time consuming activity.
The problem I have been having is as I further try to improve the usability and functionality of my current Android applications in development, and try to follow the guidelines laid out by Google for simple things such as various different icon sizes depending on different screen resolutions, this process is eating all my time!
Table 1. Summary of finished icon dimensions for each of the three generalized screen densities, by icon type.
Icon Type | Standard Asset Sizes (in Pixels), for Generalized Screen Densities | ||
---|---|---|---|
Launcher | 36 x 36 px | 48 x 48 px | 72 x 72 px |
Menu | 36 x 36 px | 48 x 48 px | 72 x 72 px |
Status Bar (Android 2.3 and later) | 12w x 19h px (preferred, width may vary) | 16w x 25h px (preferred, width may vary) | 24w x 38h px (preferred, width may vary) |
Status Bar (Android 2.2 and below) | 19 x 19 px | 25 x 25 px | 38 x 38 px |
Tab | 24 x 24 px | 32 x 32 px | 48 x 48 px |
Dialog | 24 x 24 px | 32 x 32 px | 48 x 48 px |
List View | 24 x 24 px | 32 x 32 px | 48 x 48 px |
I aim for all the icons I use to be in SVG format simply because they scale well and and can be easily converted to the desired format, PNG in this case. I use Gimp for windows to convert all the SVG files I have to the various different PNG's. This process is very manual and very time consuming which got me thinking......
After a little Google I stumbled across an Apache project for XML image manipulation called Batik. It seemed vast and very comprehensive but thought I'd give it ago.
I created a simple Groovy script which wraps Batik, exposing some Android orientated functionality cutting down the time to convert images from minutes to seconds, and when you start trying to convert larger numbers of SVG's to PNG in various sizes with the same name outputting them in different folders it can take hours.
I simply define various required image size groups which hides the mess and allows me to simply say I want this SVG converted to the required ANDROID_TAB dimensions.
Below is what I ended up with.
class SvgImageCreator { public static void main(String[] args) { new SvgImageCreator().convert(SizeGroups.ANDROID_DIALOG, [ "menu_bug", "menu_clear_stats", "menu_credits", "menu_email", "menu_improvement", "menu_play_again", "menu_settings", "menu_manage_groups", "menu_add_group" ]) } def convert(def sizes, def filesToConvert){ filesToConvert.each{ file -> sizes.eachWithIndex { i, index -> println """Converting ${file} to W:${i[0]} H:${i[1]} for folder: ${SizeGroups.FOLDERS[index]}""" convertToPng(file, SizeGroups.FOLDERS[index], i[0], i[1]) } } } def convertToPng(def name, def folder, def width, def height){ final SVGConverter svgConverter = new SVGConverter(); svgConverter.setSources(["images/svg/${name}.svg"]as String[]); svgConverter.setHeight(height); svgConverter.setWidth(width); svgConverter.setDst(new File("images/${folder}/${name}.png")); svgConverter.execute(); } }

After thinking about this over night, you could extend this to be quite intuitive, creating an eclipse plug-in which scans chosen folders outputting images of various sizes depending on file naming conventions. You could also have this as a standalone runnable jar which you booted up when you started development and performed the required actions after looking at a definition files in which would layout the conversions to and from. Obviously it doesn't do that at the moment and to be honest it has solved my problem saying me vast amounts of time as it stands so hopefully someone else may also benefit from it.
Please feel free to check out my GitHub where all the code is available: https://github.com/jamesemorgan/AndroidSvgToPngConverter. As ever comments are always welcome.
To get the project running simple clone the above project and add the missing dependency on Batik by downloading the source files from http://xmlgraphics.apache.org/batik/Groovy Eclipse plugin installed you should be fine.
An example of the above images used in and Android menu can be seen below:
An example of the above images used in and Android menu can be seen below:
Sunday, 8 May 2011
Reading Files inside a jar file correctly
Recently I've ran into some problems when trying to create a simple jar package containing multiply SQL files which in-turn would be ran against several databases. The application isn't complex, but simply a utility application which would be ran once a week/month against very large data sets in order to clean up data and fix known issues. The jar file would be invoked via a cron script and left to run over several hours on a weekend. I used the maven-assembly-plugin to build the jar file, simply specifying the main method to invoke.
First time I tried to deploy the program when it ran, all the files where trying to be loaded via a none relative path, i.e. trying to access files on the files system not inside the jar itself. After several different attempts at trying to read in files I found a simple solution using Google Guava.
Google guava has many helpful and functional utility libraries, commonly I use classes in:
This utility class simply wraps the use of the Files and Resources class in side google.io to expose a few cleaner utility methods which will in turn be used to load any text files needed. The solution is neat and simple, and since the project already has a dependency on the Google guava the over head is minimal.
All in all, Google Guava contains a very useful set of utility classes which in my opinion should almost be as standard as using the Apache Commons libraries.
All source code, tests and the original class I created with many good/bad and ugly attempts as over coming this problem can be found on my Git Hub account @ https://github.com/jamesemorgan/SampleJarReading
First time I tried to deploy the program when it ran, all the files where trying to be loaded via a none relative path, i.e. trying to access files on the files system not inside the jar itself. After several different attempts at trying to read in files I found a simple solution using Google Guava.
Google guava has many helpful and functional utility libraries, commonly I use classes in:
- com.google.common.io - Utility methods and classes for working with Java I/O, for example input streams, output streams, readers, writers, and files.
- com.google.common.collect - Generic collection interfaces and implementations, and other utilities for working with collection.
- com.google.common.base - Basic utility libraries and interfaces.
/** * @author James Edward Morgan */ public class ResourceFileLoader { /** * @param location * @return a {@link String} {@link List} of all lines in the file * @throws IOException * @throws URISyntaxException */ public static ListreadLines(final String location) throws IOException, URISyntaxException { return Files.readLines(new File(Resources.getResource(location) .toURI()), Charsets.UTF_8); } /** * @param location * @return The {@link File} Resource * @throws URISyntaxException */ public static File readFile(final String location) throws URISyntaxException { return new File(Resources.getResource(location) .toURI()); } /** * @param location * @return String the complete loaded file * @throws IOException * @throws URISyntaxException */ public static String readAll(final String location) throws IOException, URISyntaxException { final StringBuilder builder = new StringBuilder(); for (final String line : Files.readLines(new File(Resources.getResource(location) .toURI()), Charsets.UTF_8)) { builder.append(line); } return builder.toString(); } }
This utility class simply wraps the use of the Files and Resources class in side google.io to expose a few cleaner utility methods which will in turn be used to load any text files needed. The solution is neat and simple, and since the project already has a dependency on the Google guava the over head is minimal.
All in all, Google Guava contains a very useful set of utility classes which in my opinion should almost be as standard as using the Apache Commons libraries.
All source code, tests and the original class I created with many good/bad and ugly attempts as over coming this problem can be found on my Git Hub account @ https://github.com/jamesemorgan/SampleJarReading
Wednesday, 27 April 2011
Integrating Google Analytics into Android
One of the many things on my development list for the current Android projects I'm developing has been to integrate some form of user tracking/feedback functionality into the application.
Ill show you how I went about integrating Google Analytics into a sample application explaining some of the reasons and decisions I took along the line.
API's/Library
After a quick Google and a little bit of reading there seems to be a serious lack of available Google Analytics API's for android. One alternative is a paid Analytics tool from usermartix but since its not free it doesn't really help me for the example so I'm sticking with Google's own Analytics SDK for Android.
Prerequisite
I'm going to presume you have eclipse or a similar IDE installed with the Android SDK and IDE plugin set-up and installed. Installation instructions are available in the getting started section of the Google Mobile SDK docs.
For this example the code will work on Android 1.6 and above (a.k.a Donut) All code can be found at my GitHib repository @ https://github.com/jamesemorgan/AndroidGoolgeAnalyticsDemo
1) First create a new "Android Project" in Eclipse giving your application a name, package structure and specifying Android 1.4, API level 4.
If you haven't create an Android Emulator yet, plenty of information can be found on-line but the best way is to use the AVD manager which gets installed with the SDK and can be launched directly from eclipse.
2) Download the Google Analytic SDK, unzip it and place the jar in your libs folder or simply add it to your build path of the project as seen to the left.
3) Add the following lines to your AndroidManifest.xml file in order to enable to use of the Internet when you deploy your application. An exception will be thrown if not.
Creating Your Abstract Activity
public class AbstractAnalyticActivity extends Activity { private GoogleAnalyticsTracker tracker; @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get and set the Google Analytic tracker instance setTracker(GoogleAnalyticsTracker.getInstance()); // Get application shared preferences final SharedPreferences preferences = getSharedPreferences("SomeSharedPreferenceKey", Activity.MODE_PRIVATE); // Get your preference key for enabling google analytics final boolean enabledGoogleAnaltyics = preferences.getBoolean("PREF_GOOGLE_ANALYTIC", true); if (enabledGoogleAnaltyics) { // Arg1: Your tracking ID // Arg2: How often your tracking events get dispatched to google, set to 20 seconds // Arg3: The activity to track tracker.start("UA-XXXXXXXX-X", 20, this); } else { // Stop the tracker if not enabled tracker.stop(); } } private void setTracker(final GoogleAnalyticsTracker tracker) { this.tracker = tracker; } public GoogleAnalyticsTracker getTracker() { return this.tracker; } }
Above is the class I created to encapsulate all Google Analytic logic.
- First create a GoogleAnalyticsTracker variable, with a public getter and private setter thus to only allow subclass's the ability to retrieve the tracking class.
- Secondly, as with most Android Activities you must override the onCreate method which is where I place all set-up code for the Google Analytic tracker.
- Replace UA-XXXXXXXX-X with your Google Analytics account ID. Again plenty of instructions/guides online can be found on how to do this.
- In addition to any Analytics code I have also included an example of how to retrieve application user preferences in order to give the user the ability to disable tracking if they wish so. (Lines 13-16) I believe this should always be the case when tracking a users movement you should always give them the option to not be tracked. I believe visibility and trust is key to a successful user/developer relationship.

Create your Activity
In order to track an event, I simply retrieve the tracker from the parent class and set what page view I want the tracking to be registered as. I've done this for each button declared in the main.xml file mentioned earlier.
Don't forget that Google Analytics is 24 hours behind and will not show you any analytics data straight away. Don't be surprised if your newly created account doesn't show anything straight away.
public class AndroidAnalyticsDemoActivity extends AbstractAnalyticActivity { @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set you main view, i.e. your GUI xml file setContentView(R.layout.main); } public void onStatsClickgetTracker().trackPageView("/DashboardStatsActivity"); } public void onGroupsClick(final View v) { getTracker().trackPageView("/DashboardGroupsActivity"); } public void onFriendsClick(final View v) { getTracker().trackPageView("/DashboardFriendsActivity"); } public void onHomeClick(final View v) { getTracker().trackPageView("/DashboardHomeActivity"); } @Override protected void onDestroy() { super.onDestroy(); // Stop the tracker when it is no longer needed. getTracker().stop(); } }
Conclusion
Google Analytics provides a quick and simple way of tracking application views and events inside your Android application. I've only shown you how to track page views but as with most things, a plethora of information is available on the Internet about this useful and intuitive API.
Subscribe to:
Posts (Atom)