FinanTrak iPhone version is now available for download.

http://itunes.apple.com/us/app/finantrak/id491256295?mt=8&ign-mpt=uo%3D2


I’ve developed a personal finance tracking application named FinanTrak. Its features include:

* Multiple accounts, 4 account types
* Charts, monthly budget, transactions verification
* Backup and restore, export to CSV
* Password protection

Both full and free versions are available in the Android Market.


Our paper “A 2D Barcode Validation System for Mobile Commerce” got accepted and will be published in IJHCR http://www.igi-global.com/ijhcr/


My first paper “A 2D Barcode Validation System for Mobile Commerce” has been published in the GPC 2010 conference proceedings.

More info on the GPC2010 conference: http://gpc2010.ndhu.edu.tw/

My paper: http://www.springerlink.com/content/m0367v103xmt2273/


Android has a built-in testing framework that includes a subset of JUnit.  All of its test-case classes are directly or indirectly derived from JUnit’s TestCase.  If you’re already familiar with JUnit, it’s not that difficult to use the Android Testing Framework.  The Android SDK has some sample testing programs in android-sdk-mac_x86-1.5_r1/platforms/android-1.5/samples/ApiDemos/tests.  Here are some common testing classes in the framework:

TestCase – Plain old JUnit test case.  It can be extended to test utility classes that are not tied to the Android framework.

AndroidTestCase – It extends JUnit’s TestCase.  It’s a lighter testing class compared to ActivityTestCase.  It doesn’t need to launch an activity to run it.  Its getContext() method allows you to get an injected context if you need one.  Since you can get a context from this class, you can inflate your UI objects to test their behaviors.  However, the UI behaviors will not show in the emulator.  I like to use this class to test my data access objects.

ActivityInstrumentationTestCase2<T extends android.app.Activity> – It’s the newer version of ActivityInstrumentationTestCase.  ActivityInstrumentationTestCase is deprecated in Android SDK 1.5.  It’s a heavier testing class compared to AndroidTestCase.  It provides UI and functional testing for a single activity.  You can get an injected activity that you are testing on by calling its getActivity() method.  The activity being tested is launched and finished before and after each test.  Since the activity is launched for each test, you can see how the UI is being tested in the emulator.

ActivityUnitTestCase<T extends android.app.Activity> – It gives the tested activity an isolated environment.  When using it to test an activity, the activity is not attached to the system.  This gives you more control over what kind of environment that you want your activity to be tested in.

ApplicationTestCase<T extends android.app.Application> – It provides testing for Application classes.  It can be used to test the life cycle of an application.

InstrumentationTestRunner – The runner that runs the Android test cases.

The class diagram of those classes probably looks something like this (NOTE: Not all the attributes and operations are listed):

testing-framework

Here is how to create a sample testing project in Eclipse to test the NotesDdAdapter object of Notepad3 (Android’s Notepad tutorial).

  1. Create the Notepad3 project in Eclipse.
  2. Create an Android project in Eclipse called Notepad3Tests.  Make sure the Create Activity option is unchecked.
  3. Make sure Notepad3′s bin folder is included in the build path of Notepad3Tests.
  4. Add this class to the Notepad3Tests project.  It’s the sample code that tests NotesDbAdapter’s createNote(…) function.
  5. public class NotesDbAdapterTests extends AndroidTestCase {
    
        private static final String TAG = "NotesDbAdapterTests";
        private NotesDbAdapter dbAdapter;
    
        @Override
        protected void setUp() throws Exception {
            super.setUp();
    
            // Do some initial setup here
            Log.d(TAG, "In setUp");
            dbAdapter = new NotesDbAdapter(this.getContext());
            dbAdapter.open();
        }
    
        @Override
        protected void tearDown() throws Exception {
            super.tearDown();
    
            // Do some clean up here
            Log.d(TAG, "In tearDown");
            dbAdapter.close();
        }
    
        // Test createNote
        public void testCreateNote() {
    
            long id = dbAdapter.createNote("this is title", "this is body");
            Log.d(TAG, "Note id: " + id);
            assertTrue("Failed to insert note", id > 0);
        }
    }
  6. Modify the AndroidManifest.xml file in the Notepad3Tests project.  a) Click the Application tab.  Under the Application Nodes, add a Uses Library node.  b) Click the node that you just created.  In the Name field on the right, add android.test.runner.  I don’t know why this has to be done since there is not much information about android.test.runner.  c) Click the Instrumentation tab and add an instrumentation.  d) On the right side, in the Name field, add android.test.InstrumentationTestRunner.  In the Target Package field, add com.android.demo.notepad3.
  7. Run Notepad3 so it can be installed on the emulator.
  8. Run NotesDbAdapterTests by selecting Run As > Android JUnit Test.

For more information, please refer to the files in android-sdk-mac_x86-1.5_r1/platforms/android-1.5/samples/ApiDemos/tests.


YaMovies

21May09

YaMoviesI made a small Android program, YaMovies, that parses the RSS feed of weekend box office from Yahoo Movies. It uses two threads to load the movie data and images. The first thread parses the XML file retrieved from http://rss.ent.yahoo.com/movies/thisweek.xml and creates an array of movie objects. In the XML file, each movie has an URL to its image. The URL is parsed and stored in the movie object. The second thread iterates through the movie array and loads the images from their URLs.

The Android SDK has Apache HTTPComponents for you to make HTTP requests and process HTTP responses. For example, to make an HTTP GET request to the RSS feed:

HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet("http://rss.ent.yahoo.com/movies/thisweek.xml");
ResponseHandler responseHandler = new BasicResponseHandler();
String responseBody = client.execute(httpGet, responseHandler);

The responseBody contains the weekend box office information in the XML format. Now it needs to be parsed to extract the information. Fortunately, Android includes SAX and provides an XML parser called Xml. It makes the parsing easy.

Xml xml = new Xml();
MovieSaxHandler movieSaxHandler = new MovieSaxHandler();
xml.parse(responseBody, movieSaxHandler);

The only thing that’s needed is a SAX handler. MovieSaxHandler, extended from SAX’s DefaultHandler, was created to capture the parsed data and create movie objects. When creating a SAX handler, most likely you would override its characters(…) method to get the content of an XML element. However, when the method is called by the parser, make no assumption that all the content will be passed in at once since the parser might consume the content in chunks.

You can download the source code from here.


I recently found a small problem with Axis2 when I was building a POJO service with the code-first approach. I started off with the service’s interface and then generated its WSDL file using Axis2′s Java2WSDL tool. In the generated WSDL file, I noticed that the parameter names of each service were not generated correctly. For example, let’s say you have the following service in your Java interface:

public interface Service {
    public void updateName(int id, String name);
}

The generated WSDL file:

<xs:element name="updateName">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="param0" type="xs:int"/>
            <xs:element minOccurs="0" name="param1" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

The parameter name “id” is replaced with “param0″ and the parameter name “name” is replaced with “param1″. This makes your service hard to understand for whoever wants to use it.

However, if you create a POJO service without separating its interface and implementation, the parameter names are generated correctly in the WSDL file. For example:

public class ServiceWithImpl {
    public void updateName(int id, String name) {
        /*
         * Do something there.
         */
    }
}

The generated WSDL file of ServiceWithImpl:

<xs:element name="updateName">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="id" type="xs:int"/>
            <xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

This solves the problem but makes the code inflexible.

I’m using Axis2 1.4.1. If you know any other way to get around it, making Axis2 generate the correct parameter names by giving an interface, please let me know. Thanks.




Follow

Get every new post delivered to your Inbox.