Sunday, 4 January 2015

Integrating Google Analytics into existing Android app

Analytics are key to measuring the success of your project or application and are a great way of identifying your users trends and demographics. Have you released an app and wondered who your users actually are? Well with analytics you could find out where your users are situated, what ages they are etc. The leader in this field is Google Analytics - this can be embedded into your mobile application, website and even your blog.



After a few frustrating attempts at integrating Google Analytics into an existing app I thought I should post a guide on how to do this.

1. Download the Google play services library and add it to your project.

You can do this by right clicking on the project you want to add analytics to in eclipse, choosing properties and then the Android tab. In the Library section, select Add and choose google-play-services_lib and select Apply.

2. Add the required permissions to AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

These are required so your app can send the analytics content.

3. Add Metadata to your application. This should be added under the application tab.

<meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
<meta-data
            android:name="com.google.android.gms.analytics.globalConfigResource"

            android:resource="@xml/global_tracker"/>

We'll add global_tracker later.

4. Create the analytics application helper class.

import com.google.android.gms.analytics.Logger;
import com.google.android.gms.analytics.Tracker;
import com.google.android.gms.analytics.GoogleAnalytics;

import android.app.Application;

import java.util.HashMap;

public class YourApplication extends Application {

    // The following line should be changed to include the correct property id.
    private static final String PROPERTY_ID = "YOUR_ANALYTICS_ID";

    public static int GENERAL_TRACKER = 0;

    public enum TrackerName {
        APP_TRACKER, // Tracker used only in this app.
        GLOBAL_TRACKER, // Tracker used by all the apps from a company. eg: roll-up tracking.
        ECOMMERCE_TRACKER, // Tracker used by all ecommerce transactions from a company.
    }

    HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();

    public YourApplication () {
        super();
    }

    synchronized Tracker getTracker(TrackerName trackerId) {
        if (!mTrackers.containsKey(trackerId)) {

            GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
            analytics.getLogger().setLogLevel(Logger.LogLevel.VERBOSE);
            Tracker t = (trackerId == TrackerName.APP_TRACKER) ? analytics.newTracker(PROPERTY_ID)
                    : (trackerId == TrackerName.GLOBAL_TRACKER) ? analytics.newTracker(
                            R.xml.global_tracker)
                            : analytics.newTracker(R.xml.ecommerce_tracker);
            t.enableAdvertisingIdCollection(true);
            mTrackers.put(trackerId, t);
        }
        return mTrackers.get(trackerId);
    }

}

5. Update AndroidManfiest.xml to include your application, e.g.:

<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name=".YourApplication" >

6. Create the tracker xml files. 

Under the res section in your project create an xml folder. Create two xml files in this named ecommerce_tracker.xml and one called global_tracker.xml. Contents below - remember to substitute in your analytics tracking ids. These can be created following instructions here

ecommerce_tracker.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="ga_sessionTimeout">60</integer>
    <!--  The following value should be replaced with correct property id. -->
    <string name="ga_trackingId">**INSERT TRACKING CODE HERE**</string>
</resources>

global_tracker.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="ga_sessionTimeout">300</integer>
    <bool name="ga_autoActivityTracking">true</bool>
    <screenName name="**Path to Your Application e.g. com.company.YourApplication**">**YOUR NAME**</screenName>
    <!--  The following value should be replaced with correct property id. -->
    <string name="ga_trackingId">** INSERT TRACKING CODE HERE ** </string>
</resources>

Note the trackers are described as follows by Google 

APP_TRACKER, // Tracker used only in this app.
GLOBAL_TRACKER
, // Tracker used by all the apps from a company. eg: roll-up tracking.
ECOMMERCE_TRACKER
, // Tracker used by all ecommerce transactions from a company.

7. Send the screens

Add the following code to your onCreate method in your activity. This will send the screen views to Google Analytics.

// Get tracker.
Tracker t = ((YourApplication) getApplication()).getTracker(TrackerName.APP_TRACKER);

// Enable Display Features so you can see demographics in Google Analytics
t.enableAdvertisingIdCollection(true);

// Set screen name.
t.setScreenName("** YOUR SCREEN NAME  **");
       
// Send a screen view.
t.send(new HitBuilders.AppViewBuilder().build());

8. Update onStart and onStop

Add the following:

@Override
protected void onStart() {
super.onStart();
GoogleAnalytics.getInstance(this).reportActivityStart(this);
}

@Override
protected void onStop() {
super.onStop();
GoogleAnalytics.getInstance(this).reportActivityStop(this);
}

9. View results in Google Analytics.

You are now done and once users start using your app you should be able to see real time updates in Google Analytics. Note that the analytics aren't exactly real time - but it's good enough! 


Let me know if this helps you out or if you have any further questions and I'll try and help where I can.

EDIT: 11/01/2015 - updated section 7 to allow you to display demographics in Google Analytics.

Allow Android app to install on SD card

A common problem which can turn users off your app is not having the option to transfer the app to their SD card hence clogging up their phone. Chances are they'll uninstall as soon as they can. Users may have apps such as AppMgr III (App 2 SD) installed which will automatically try and move any installed apps to their SD card.

Luckily as a developer enabling this is incredibly simple - it's one line in the AndroidManfiest.xml.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.your.package.name"
    android:versionCode="1"
    android:versionName="1.0"

    android:installLocation="auto" >

The section highlighted in green is all you need to add. You have two options here:

  1. auto - this enables the app to be installed on the SD card, but you don't have a preference and you leave it up to the user. This is the option I always go for. Once installed the app can freely move between internal and external.
  2. preferExternal - this also enables the app to be installed on the SD card but you also try and install it there by default if there is available space. If there isn't it will default to internal phone storage. Once installed the app can freely move between internal and external.
That is all there is to it - a one line change which makes a massive difference to your user retention rates. The full documentation can be found here.

Friday, 2 January 2015

Update eclipse Android Development Toolkit to version 23.0.0

I hit the following irritating issue when I started eclipse up recently.

"This Android SDK requires Android Developer Toolkit version 23.0.0 or above. 

Current Version is 22.6.3.v201404151837-1123206. 

Please update ADT to the latest version." 



The really irritating thing was that clicking on Check for Updates found no updates! After a lot of different attempts, here's the steps I used to resolve this.

1. In Eclipse go to Help -> About Eclipse SDK


2. Click on "Installation Details".



3. Select Android Development Tools and click the uninstall button. You will need to restart once this is finished.


4. Now select Help-> Install new software.


5. Expand Developer Tools and select Android Development Tools and select next


6. Click next a few times and then finish.The installation will then begin. Accept any warnings about unsigned content. 

7. You'll be asked for another restart. Restart now.

  
Eclipse should now open with no errors. I hope this helps. I tried following others steps from stackoverflow  but had no success but these steps worked a treat. 

NOTE: At step 2 and 3 you can choose to uninstall all of these options and update all. In this article I focused on only the Android development tools.

Wednesday, 31 December 2014

Technology Radar for 2015

With 2014 drawing to a close and 2015 offering fresh opportunities it is up to every software development professional to look at the up and coming technologies which are becoming widely adopted. ThoughtWorks have released their technology radar for 2015 with a list of techniques, tools, platforms, languages and frameworks to either adopt, trial, assess or avoid in the coming year. This is well worth a read - I have to say there were quite a few which I hadn't looked at before - a prompt reminder of how quick it is to fall behind in this profession.

Here's my two tips for 2015 - the top technologies to either adopt or trial in any new projects you are working on.

AngularJS
AngularJS is an excellent JavaScript framework which when used effectively allows you to structure your code to make complex web applications easily maintainable, and promotes code re-use. While the latest version (1.3) is extensively used in both small and major projects across the world, the AngularJS team are working on a re-write for version 2 in order to address some potential performance problems. The bad news is that version 2 is not a simple upgrade and will require people to re-write their apps. However, it is unlikely that projects started in 1.3 will need to upgrade - 1.3 is perfectly sufficient. Anyone starting a new project should consider closely whether they should start with version 2.


Docker
Docker has exploded onto the scene this year with people utilizing docker in both development environments and now production environments. Docker describe the product as follows:

"Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications. Consisting of Docker Engine, a portable, lightweight runtime and packaging tool, and Docker Hub, a cloud service for sharing applications and automating workflows, Docker enables apps to be quickly assembled from components and eliminates the friction between development, QA, and production environments. As a result, IT can ship faster and run the same app, unchanged, on laptops, data center VMs, and any cloud."



With Microsoft working on supporting docker in the next version of windows server I think it's fair to say Docker is a major player in the fast moving software container field.

I'd be delighted to hear what technologies you tip to be big in 2015 - have a great new year!

Tuesday, 30 December 2014

Tutorial: Create great icons with Syncfusion Metro Studio

A key part of any website, desktop or mobile application is icons. These tiny little images can really bring your project to life and improve the look and feel of your apps. Choosing the wrong icon can have a huge impact on the usability of your application. I found creating or finding icons for my projects could be a real time waster - until I found Syncfusion's free desktop application - Metro Studio.

Metro Studio comes with over 4000 pre-made icons which you can customize to meet your needs - change the colors, change the size and export them to any format you want. Here's a quick run through of how to use Metro Studio.

When you open the application you will be shown a list of available icons to choose from:


Here you can browse by category and the search feature is great - finding similar icons. Lets assume we want a shopping basket and we select that icon:



The icon is shown (and defaults to your last configuration - so you can maintain color consistency). On the right hand side there are options for shape, size, transparency, rotation and color.



You can also create a project and edit multiple icons at once, great if using icons for buttons to ensure consistent styling.


There are various export formats for example bitmap, ico and png. A great tool to prevent stalling applications.



Tuesday, 16 December 2014

Situational Leadership in Agile

For anyone line managing as well as performing technical leadership, the term situational leadership may have come up in an HR lecture you really don't care about! Join the club.

However, this was once explained to me in terms that really struck home to me and is something that I have learned the hard way in my teams.

Agile works because the team is empowered to succeed - to a certain degree a lot of responsibility is delegated onto the team.

Situational leadership is the theory that there is no right way to manage - but effective leaders effectively bounce between styles. The styles are:

  • Telling/directing - the leader tells subordinates what to do.
  • Selling/coaching - the leader sells an idea so that subordinates will do it.
  • Participating/supporting - the leader will work with subordinates to get the desired outcome.
  • Delegating - subordinates are essentially able to pick up the work themselves. 


At its most effective, Agile works when most of the team are at the delegation stage. The team responds well to the responsibility and will work efficiently and take ownership of their tasks. This however can cause conflicts when the leader suddenly treats subordinates at the tell or sell stage. Why does he/she no longer trust us to do this work? 

This can usually be explained as either of the following reasons:
  1. The work is urgent and the leader needs to get involved closely to ensure it is done.
  2. The work is new or a change in direction in the team, and the leader needs to explain to the team why we need to make the changes. 
What I have learned the hard way is that you need to explain to your team this model so they understand why you are no longer delegating this specific task. If you can explain to the team you are currently at the stage where you need to tell for some reason, explain you are in the tell stage, why, and that normal service will be resumed soon and it will switch back to delegate. I find teams respond well to this and it removes any tension or hurt feelings in the team. 

Another thing that it's vital to remember as the team are acting in the delegate stage is that ultimately you are responsible. This means that even though you trust them to do the work, you need to take responsibility for it and that to do that you need them to report back with what they are doing and why decisions are made. Explain the situational leadership model to them and they will appreciate this. Reporting back to you helps you defend their decisions if they are questioned. 

The Tannenbaum and Schmidt's leadership model is a slightly different visualization of situational leadership but it explains the delegation/responsibility issue above really well.


Note that in the top right, the line never reaches the top right. That is because no matter how much you delegate, you as the leader/scrum-master/development manager are always responsible. Again explain this to the team and it will help resolve any conflicts.

Continuous integration is the key!

Continuous integration (CI) is a key component of any successful software development team - not just an agile team. Doing it right will bring the following benefits to your team:

  • Provide automated builds of software for testers to pick up. 
  • A common, repeatable platform to run tests (unit, integration, automated functional and performance tests).
  • A place to run code quality tools (SonarQube, FxCop, StyleCop, JSHint etc)
  • A place to create production build installers. 
There are various great tools for setting up continuous integration and you should spend time evaluating what will be best for your project. My personal favorites are: 
It is imperative that an agile team devotes time early in their project to get their continuous integration system up and running early (sprint 1 or 2) to ensure they have a solid platform to run on. Ideally your continuous integration will run on every commit into your source control system so that the team gets immediate feedback - have the changes compiled, have the tests run, is the code quality good. In the past in teams I have configured our continuous integration system to play a siren out loud in the office if the build has broken. The public nature of a central build location ensures extra care is taken by each team member when submitting their changes. 

For continuous integration you will need the following infrastructure at a minimum:
  • A server for builds, running the tests etc. 
  • A source control system (e.g. GIT, SVN, CVS)
For larger projects you may scale this up to have multiple agents running builds and tests. 

A common mistake teams make when creating their CI system is to not share knowledge of its workings with enough team members. Ideally everyone needs to know how it works - from developers to testers. These things need maintenance now and again and you want to spread the load, and have multiple people who can pick up the task. 


Once your continuous integration environment is setup and successful, you then need to look at automatic deployment - I'll write a future blog for this. Automated or continuous deployment is the next logical extension of your CI environment where you automatically build a new version of the system for test purposes perhaps or even automatically updating your production environment depending on your project.  Again with a little up front effort, the long term benefits can be huge!

Covid-19 impact on mobile applications - a quick case study

Amidst everything that's been going on over the last few months, checking on how my apps have been doing has been low down my priorities...