Open source, coffee and us….

Archives

Using Bitmaps and Bitmasks

Having been wrestling with the refactoring of some existing android code written by third-parties, I was deliberating over some data structures that seemed very unwieldy and enhancement unfriendly.  This involved using a child table to my main data store to hold various flags to indicate some dynamic property of the main data that could be used for filtering a query.  There was nothing in these child tables apart from flag identifiers,  and as a result there is a need to build a complicated sql statement with an outer join and a set of OR predicates for each flag required (or not required).

It did not take too long to recognise this as an ideal candidate for refactoring to use bitmaps and bitmasks to achieve the requirements in a much simpler manner.

These were the steps I took:

  • Add an integer column called ‘flags’ to my main table
  • Create a class containing final static int Constants for each required flag where the values equate to binary orders, i.e. 1,2,4,8,16,32 etc. , bearing in mind there is a limit to the size of ints and therefore the number of values that can be stored.
  • To populate the flags field we just need to add together all of the required flag constants.
  • To add a new flag we just add the flag constant to the existing flags field
  • To remove a flag, we can subtract the flag constant
  • To check whether  any flag is set we just need to do a bitwise  comparison of the current value with the flag value, i.e. the flag is set if flag == (value | flag)
  • We can also check for flags that are not set by comparing the flag in a similar manner with a bitmask which equates to the sum of all the possible values minus the ones that we are checking against.

With such a structure, we can then construct a sql filter that consists of a single where clause, e.g. where Table.tags | bitmask = bitmask.

This then provides and elegant and flexible solution to the problem, that can easily form part of a more complex sql filtering requirement

You’ve published your Android application – now what?

This is the third in a series of articles related to publishing your application to market place.

The earlier ones are Managing free and paid Applications and Preparing your app for market – a checklist

Your application has been published to the market place, and I guess you’re now monitoring your download figures – no doubt with fingers crossed that it will take off big time. There are two activities which now have to start happening.

The first  is that somehow the world has to get to know about your application.

People may come across it via searches in the marketplace but you should be actively promoting it in the wider world using every means at your disposal – twitter, facebook, website etc etc. You can also use other distribution channels,  with Android applications you are not only limited to the Google Android Market place. There are others such as those provided by carriers eg Orange and you could also make your application directly available from your own website.

These are exactly the same activities you would do to publicise and sell  any other product, and I’m sure you will have already started doing them in parallel with the development and deployment stages of your application. If not then now is the time to start.

And now we come to the second set of activities – in a word ‘Analysis’.

Wherever your application is being distributed, you are no doubt beginning to collect some basic statistics like those supplied in the Google marketplace  ie number of installs, number of active installs and any feedback comments that have been provided. And it is when looking at this information that you realise it is not enough.

You need to know:

Why did people install and then uninstall?

Was it not what they expected from the market place description or the application name?
Did it lack a feature they wanted?
Did it not work on their device? What device? At all or simply inappropriate layout, text or graphics not appearing etc
Some other reason?

Are you getting any feedback from the active installs – are they happy with application, are there new features they would like to see added?

The comments provided in the marketplace can be sparse and are primarily geared to assist other people in making a decision to download your app or not. For you  as an application provider they tend not to be helpful and just raise more questions to which you would like answers. It would be really good if you could enter into a dialogue with the commentators.

The upshot of all this is that you need feedback from the users of your application and you need to provide the means of doing so. The easier it is for a user to provide feedback the more likely you are to get it, and the easiest place is from within your application itself.

Ways in which this could be achieved include:

  • Links to your website FAQ, email etc or at the very least the standard market feedback page for your application. These links could be placed on your Help or About page, or a recent changes page that is shown when updates take place
  • On the Marketplace page make sure your contact details are prominent including FAQ, and help pages on your website
  • A mechanism at uninstall time for capturing the reasons why the application is being uninstalled. The users may decline to give any but if it is easy to do so – set of checkboxes to select from  maybe – then you are more likely to get a response.

More detailed usage of you application can be gleaned from the use of Google Analytics. By implementing Analytics in your applications you can start to determine the usage of functions and features within the application itself.

Once you have answers to all of these questions, you can start to refine your application so that the active install count stays proprotionally high, and all the comments are 5 star rated.

Now go and have another peek at your download stats… 🙂

Preparing your Android app for market – a checklist

That’s it!  Finished.

The last piece of code for your app has gone in and the tests are all passing successfully.  Now you can release it to the marketplace.

Or can you?

See this Google checklist for what should be done before you can say that.

The rest of this post will highlight other steps you should be taking in getting your application ready for market.

The first question is which marketplace will you be releasing it to? For the purposes of this article I am assuming that it is the Google Marketplace.

There are other 3rd party marketplaces around and for those I would imagine that the information you need to supply will be fairly similar.

So let’s assume that you have already registered with Google’s Marketplace and set up all of your payment options for the stream of money you will be getting.

So what is left in order for you to make life easier for yourself when releasing your application.

  1. Is your application free or paid for? If you plan on offering both versions you might want to check our earlier blog entry on how best to organise your code to support both free and paid for versions.
  2. If your application is a paid for application, then you may want to investigate using Google’s Licensing service for it. Again this is something that probably needs to be decided earlier in the process as you will need to add code to your application to support its use.
  3. Look at the Google checklist mentioned above – this should be used first as there are some things there that need to be done before we even get round to thinking about release.
  4. One of the items in the above list is turn off logging and debugging. There are a number of ways of achieving this but the easiest solution we have found is to use Proguard configuration settings in your eclipse project which filters out Log statements as part of obfuscating your released code. You are obfuscating your code aren’t you?
    In your proguard.cfg file add the following lines:

    -assumenosideeffects class android.util.Log {
        public static *** d(...);
        public static *** v(...);
    }

    You will also need to add the following line to the default.properties file in your project:

    proguard.config=proguard.cfg
  5. Also if you are using Proguard to obfuscate your code make sure that you save the generated mapping.txt file, ideally tagged in your version control system along with the release application code. Without the matching version of this file you will not be able to interpret any stacktraces etc which will be showing the obfuscated values.
  6. If your applications is making use of advertising ensure that any test ad settings you have, are switched to live ads.
  7. In order to register your application on the marketplace you will also need a variety of graphical assets – some mandatory and some optional. A summary can be seen below and detailed specifications of sizes, resolutions etc for these assets can be found here:
    1. Screenshots – minimum of 2 required, maximum of 8 – mandatory
    2. High resolution application icon – mandatory
    3. Promotional graphic – optional
    4. Feature graphic – optional
    5. Video link -optional
  8. Screenshots can be easily acquired using eclipse and the emulator.
    Open the DDMS perspective,
    Select the emulator device in the Device view,
    Right click the view menu down arrow,
    and then selecting ‘Screen Capture’  from the drop down menu.
  9. Decide on the rating you are going to give your application – be aware that you cannot have a rating of ‘All’ if your application accesses location data. More precise information on ratings can be found here.
  10. Prepare any supporting pages you might want on your own website, and decide on the support methods you will provide to your users. This could be any of or all of the following: a link to your website, an email address or phone number

Finally  release your application and feel that surge of satisfaction of a job well done – and hopefully where appropriate the tinkling sound of cash.

Unit Testing with Maven and Android

The default android development environment provides for testing applications using test applications that are deployed onto the target device and exercise the actual application within the android environment itself.  But what if you have non-android dependent code that you need to test without the overhead of a full build and deploy cycle (i.e. unit testing rather than integration testing)?

If you try and include unit tests in your standard application to fail the build prior to the apk being built or deployed you will need to make some significant changes to the standard ant build.xml in order to remove the test classes from the apk itself, and expose yourself to having to manage changes to the base build with new android versions.

Building the project using the maven android plugin makes the configuration for performing unit testing far simpler.  However, none of the provided samples show how to configure the unit tests particularly well, as they provide no unit test classes.

The main thing is to make sure that the build section specifies the testSourceDirectory, e.g.

<build>
 
   <sourceDirectory>src</sourceDirectory>
   <testSourceDirectory>test</testSourceDirectory>
.
.
</build>

You can then include jUnit (or testNg or other framework) to your test dependencies, and place unit test code under the test folder in the project root directory.  Running mvn test will now run all of your tests and halt the build if there are failures.

Note that in many cases tests will fail if there is any dependency on android classes at all (watch out especially for android.util.Log .  This can be overcome using Mock implementations, especially with tools such as jMockit, which allows mocking of final classes, static methods, partial mocking etc.

More of this later.

Android TabHost fun

My initial impressions were that using a TabActivity to divide the task in hand up would be a good idea, and would be realtively straightforward, but as in all things once you start getting into the detail, little things crop up that cause you no end of consternation and grief.

Firstly, the documentation for View based tabs rather than Intent driven tabs is a little sparse, and in this instance I had no need to sub-divide things in that way. However, for straightforward XML based views, all works well. For detailed views it is worth separating each tab out into their own layout files, e.g.

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
 
    <TabWidget android:id="@android:id/tabs"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    </TabWidget>
 
    <FrameLayout android:id="@android:id/tabcontent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
 
        <include layout="@layout/tab1" />
        <include layout="@layout/tab2"/>
        <include layout="@layout/tab3"/>
        <include layout="@layout/tab4"/>
        <include layout="@layout/tab5"/>
    </FrameLayout>
</TabHost>

The view can then be set up in the onCreate method, adding the tabs as necessary using the layout ids for each page.

This was all well and good until I decided what I wanted to do was have dynamic tabs, where certain tabs were only present if certain data items existed, and as the user could add or remove those data items, then the tabs needed to change on demand.

The logical solution is to build and rebuild the tabs during onResume. This of course leads to the first issue, which is that there is no removeTab method, so we have to use clearAllTabs and rebuild all tabs, including those which are effectively static. This reveals a slight shortcoming inside the Android code, whereby if the user was not on the first tab when clearAllTabs was called, then a NullPointerException is thrown.  The simple answer is to execute setCurrentTab(0) before clearAllTabs, but this also has interesting side effects, more of which later.

The next issue was that unlike when executed in the onCreate method, the creation of each TabSpec caused a RuntimeException as a result of not finding the layout view when using tabSpec.setContent(R.layout.tab1) for example. This was eventually solved by implementing a TabContentFactory and using that as the tabContent, e.g.

class TabFactory implements TabContentFactory {
 
@Override
   public View createTabContent(String tabName) {
 
        View v = null;
        int viewId = 0;
        if (TAB1.equals(tabName)) {
            viewId = R.layout.tab1;
        } else if (TAB2.equals(tabName)) {
            viewId = R.layout.tab2;
        } else if (TAB3.equals(tabName)){
            viewId = R.layout.tab3;
        } else {
            viewId = R.layout.tabx;
        }
        v = findViewById(viewId);
        if (v == null) {
            v = getLayoutInflater().inflate(viewId, null);
        }
        return v;
    }
 
}

This way of creating the tab content allows for the views to be inflated if necessary. The example shows a single Factory for creating multiple contents, but for more complex cases more specialised ones may be used to simplify the logic.

The next issue was to understand how the tabs are processed, and the events that occur. When the content is added to the TabHost, the tab content is created by the factory, and an internal setCurrentPage(0) is executed, resulting in the firing of the onTabChanged event, which will by default resolve the contained View. This event does not happen for subsequent additional tabs, which is sensible as you do not need to populate other views until the user wishes to see the chosen tab. Thus, the only realistic/simple way of populating the tabs is to do so using an OnTabChangeListener, which can react to the movement of the user and set up any Views accordingly.

This is where things get a little awkward for dynamic tabs, as a result of the forced setCurrentTab(0) prior to clearAllTabs. This means that the onTabChanged event is fired and any set-up performed by the TabChangeListener will be invoked. When clearAllTabs is subsequently executed, any physical views registered with the TabHost are removed, so any views saved as fields within the activity are now not linked at all. One solution for this is to make sure that any fields saved are nullified between clearAllTabs and the rebuilding of the tabs.

There is probably a lot more to look out for, but that may be covered at another time.

Managing free and paid Android applications

The way applications are managed in the Android marketplace has an impact on how you organise your code for an application that you want to present in free and paid formats.

Essentially an application is identified by its package name and it is not possible to use the same package name for both a free and paid for version. This rules out the option of using within the package some internal flag to represent the paid or free status and then switching features on or off depending on that status.

Therefore the very first question you have to ask yourself is do you want a free version and a paid for version of your application. If not, then life is somewhat easier because you have to simply decide to offer it for either one or the other.

If you do want to offer both versions then you obviously need to decide what will differentiate the two versions – typically the free version will be ad supported and / or have a reduced feature set.

So what to do?

The crudest approach to solving this problem is to clone the whole project and then maintain two separate projects, and allow the two versions diverge as much as you want.
This will work, but will give you loads of headaches down the line when you have to start applying fixes, enhancements etc in two places. That unwritten law that states if it can go wrong it will, means that at some point you will forget to do something in one of the versions and it may not become apparent for some time. You will then spend some effort trying to work out which version has the latest good copy of code and then syncing it all up again. If you are happy to go that route then good luck.

Another approach is to use a single copy of code and then manually tweak package names, resources etc at release time.
As a manual exercise this is not trivial if you have a large application, therefore it is possible to make use of ant, and develop a script which will do all of this for you. An example of that approach can be found here

There may be other approaches, but here I will describe the approach we used which makes use of the Android library facility.  Note that it is not possible to deploy an apk from a library project.

The main steps are as follows (see notes below for specific details) :

  • develop main project in Eclipse – package name net.myPackage.application
  • when ready to create the paid and free versions do this:
  • change the main project to a library project
  • create a new empty android project for the paid version net.myPackage.applicationPaid
  • create a new empty android project for the free version net.myPackage.applicationFree
  • each of these new projects is then set to refer to the main library project
  • copy the manifest content (but not the manifest header which contains the package name) from the library project to each of the new projects just created – this is because the new projects do not override or pick up the manifest information from the library project.

So what does this give us:

  • we have a common project where all of the main code and resources are kept – leading to a single maintenance point for the majority of  the application
  • any resources used in the code which are not defined in the paid or free versions of the projects will pick up the content from the library project. The implication of this is that if we wish to create a version specific resource we simply create it with the same name in either of the free or paid versions and it will use that rather than the library version.
  • therefore the free and paid for versions of the application are used simply to override resources where needed – easy to maintain.
  • possible to have a boolean resource indicating paid or free status which can be tested by code in the library project and features switched on or off accordingly. Normally the library project would have the the default paid status value of the resource, and the free version would override it to the free value.
  • the paid and free versions can be deployed and tested using the normal methods

Notes:

  • Do as much development in your main project as possible before switching it to a library version. A library version cannot be deployed as an apk and therefore any changes made after the switchover would  have to be tested with the paid and/or free version (depending on nature and extent of the change).
  • The names used in the manifext.xml of the main project which will later become the library project need to be fully specified so that they can be found from within the paid and free versions.
    ie normally one would have something like

android:name=”.Preference”

and this should now be

android:name=”net.myPackage.application.Preferences”

  • To convert a project into a library project, use eclipse Project Properties / Android and tick the isLibrary box
  • To refer to the library project from the paid and free project versions, again use Project Properties / Android and in the Library section select the Add button and then select your Library version.
  • Remember to change the application name in the paid and free versions to make them identifiable once they are installed on a device – not good if your user can’t tell them apart in the application manager.
  • One area which will involve changes to all three projects is if you make changes to the manifest.xml ie introduce new activities, change permissions, new intent filters which apply to both the free and paid for versions. If only the paid version is effected then the changes would be made to the library and paid for versions of the manifest.xml, and similarly if the change only effects the free version then the change would be made to the library and free versions of the mainifest.xml.

Internet woes

Been struggling for the last 3 or 4 days with access to the internet.

It began last week and  I first noticed it when trying to ftp files to another site – the transfer would start at normal speed and then after what looked like the initial buffers worth of data had gone across the connection would come to a grinding halt.

I was about to send an email to the support people at the other end explaining that they had a problem with their system – obviously – when I thought I’d better try sending to one of our own servers at another location. Same problem, only it was now my problem. And the nature of the problem was that my line seemed to getting disconnected and re-connected very rapidly.

Quick call to BT, and they came back after some tests saying the line looked OK and they suspected ‘something’ at my end.  To eliminate the ‘something’ they would send me a new router out.

Fair enough but was a bit surprised that a router just over 3 months old could be faulty. Was even more surprised when after talking to a few people it seemed common that things like slightly dodgy ethernet cables, adsl filters etc could all contribute to the kind of problem I had been experiencing. That’s what happens after you’ve lived with cable internet for so long – just no idea of how the adsl world live.

New router finally arrived and after installing with all new filters, cables etc internet access now seems ok.  (Apart from one laptop which seems to have taken a dislike to sending email – but it has always been a quirky little beast)

I’ve still got some more kit to connect in yet, but am hopeful that the rest will be problem free.

However, I am curious to know if there is an easier way to identify what piece of kit might be messing everything up, and how far back in your own internal network do you have to go ie could it be any ethernet cable, switch etc?

It does  seems a bit crazy to have to replace router, filters etc everytime ‘something’ is wrong, but I can understand that from the support point of view of BT and the like, then it is probably a cleaner and quicker solution for the customer.

sharing digital photos

A non-technical friend is now the proud owner of a new Canon digital SLR and a whole new world of possibilities and problems has opened up.

The image files being created by modern digital SLR cameras can be quite large and my friend had discovered the size limitations associated with attachments on free email accounts, and had asked me what they could do. Zipping of image files is not usually that effective in compressing image files down to smaller sizes so that they can be used as attachments.

I summarized what I thought the three main approaches were (without getting into image re-sizing etc using Photoshop et al) all based around what are currently free offerings.

  1. Via email. Most of the big email providers now allow largish attachments of upto 10Mb, unfortunately image files from cameras can now be much larger than the allowed limits of the free services. Google gmail (www.gmail.com) is one of the best free services for allocating space – it allows attachments up to 25Mb (and allows 7Gb of space on their servers). This means that you can send messages with 25Mb attachments ok but doesn’t necessarily mean that the person receiving the email is with a service that can accept it. Good nudge for them to switch to Google mail maybe 🙂
  2. Specialised sending service eg www.yousendit.com – these work by you uploading the file to a server and then a link is sent via to the person who is receiving the file. They then open the link in a web browser and download the file to their machine. The free services usually have a limit of 100Mb for file attachments – for larger attachments you have to sign up and pay a monthly fee. With attachments this big you could zip a set of photos together into one file and put that as an attachment
  3. You sign upto a free online web service which gives you between 1 and 10Gb online space. You upload your files to the service and depending on the service ,set the privacy restrictions on who can see your files. You can then send people a link to individual files or a folder (cf album). This would be my preferred approach. A number of particularly good services around here – here are a few : (Note the first two are general file services so no limits on file size which would effect uploading of photos)
      www.humyo.com – free acount gives upto 10Gb
      www.dropbox.com – free account gives 2 Gb free storage
      www.picasaweb.com – free account gives 1Gb free storage – this is Googles photo product and is very good – it also works well with the google picassa software which you can install on your pc for managing your photo collections. (max photo size for upload on here is 20Mb)

I discounted Flickr in the online web service because of an upload limit of 10Mb.

My friend is going to give Picasaweb a try first – and no doubt I can look forward to some snow pictures.

A new year – new beginnings…

s5wslqins3

Cheap Pills in International Sites

Cheap Pharmacyaccutane canada buy in Europe

Cheap PharmacyBuy Online doxycycline

Online

OnlineCanadian Pharmacy No Prescription

Order

Cheapbuy antibiotics no prescription

PurchaseDrugs no Prescription EUROPE
or herebuy viagra UKbuy propecia ukviagra australia and you can see more here australia pharmacy generic