Writing an Android Inventory Application

Version 1

    Background

     

    A joint effort between the developers in the Solution Center, and SES was recently completed, preparing a two day Android application development workshop in a location with no internet access.  The workshop was presented to a prospective customer to help them select an operating system, and a device vendor, for their next generation mobile solution. The workshop audience included a software development team having Windows Mobile development experience, but no Android experience.  It was requested that the following topics be discussed in the workshop:

     

    • A simple menu system.
    • Using on device database storage, synchronized with a backend server.
    • Displaying a list of all items in the database.
    • Searching for and displaying an item from the database.
    • Adding a new item to the database.
    • Creating notifications.
    • Managing the software keyboard (displayed/not displayed).
    • Scanning.
    • Messaging.
    • Configuration.
    • Dynamically change a button label.

     

     

    The customer emphasized that they would prefer to see a working application, relevant to their business, rather than unrelated code snippets illustrating each topic.  The challenge was to present all of the requested material in way that would convey the power and maturity of Android application development, and demonstrate the added value Motorola Solutions provides, in a relatively short period of time.  It was decided that a single application would be created, containing all of the elements requested, as well as Bluetooth pairing and printing using  Zebra mobile printers.  The result is an inventory application called StockChecker. The reminder of this article will discuss StockChecker, first an overview, followed by a description of some of the Android features that simplify mobile application development.  The full source code for this application is attached.

     

    Application Overview

     

    Visually, StockChecker is quite simple, consisting of just a few screens, the opening, or main screen,  an product detail screen, a configuration screen, and an add item screen.  A few other utility screens appear in the application and will be discussed as appropriate.

     

    The main screen

     

    The main screen contains a menu bar at the top, and large area at the bottom in which a list of inventory items is displayed.  A few tasks are available from the main screen, navigation by tapping items in the menu bar, drill down, that is, isolating a single item in a detailed view, and product lookup using the scanner.

     

    The menu bar contains two icons , a wrench, and a plus sign, by tapping an icon a user can navigate to different areas of the application.  Tapping the wrench opens a configuration, or preferences screen, tapping the plus sign opens the screen that is used to add inventory items.

     

    Drill down is performed by tapping an item from the list of displayed items.

     

    Product lookup is performed by simply scanning a barcode while in the main screen.

     

    Tapping an item in the list, and scanning a barcode, open the product detail screen and perform a search operation.   When an item is tapped, the search is performed using the information displayed in the list.  When a barcode is scanned, the search is performed using the information contained in the barcode.

     

    An example image of the main screen is shown below.

     

    Main.png

     

     

     

     

    Configuration Screen

     

    The configuration screen contains many different options for changing application settings (preferences).  None of the items on this screen are used to alter the behavior of the application This screen was created simply to show how XML is used to create and store preferences.

     

    An example image of the configuration screen is shown below.

     

    Configuration.png

     

     

     

     

    Add Item Screen

     

    The add item screen contains text entry fields that are used to describe an inventory item, product Id, description, price and quantity.  The product id can be entered manually using the soft keyboard, or by scanning a barcode.  The remaining fields are populated manually using the soft keyboard/keypad.  When a barcode is scanned the database is searched, if a match is found the item details are displayed, permitting a user to alter and commit changes (update), if the item is not found them remaining fields can be populated and the item added to the database by tapping the Add button.  If a product Id is entered manually, the behavior is identical, search for the item, if found, go into update mode, if not found, go into add mode.

     

    An example image of the add item screen is shown below.

     

    Add.png

     

     

     

     

    Product Detail Screen

     

    The product detail screen is similar in appearance to the Add item screen, with two main differences, items cannot be add/updated from this screen, this screen contains a print button.  The print button will send the displayed information to a Zebra Bluetooth printer.  When the print button is tapped the applications checks if a Bluetooth printer is paired with the device.  If a printer is not paired with a printed the user will be presented with a screen that explains how to pair the device with a printer, using either the scanner or using NFC.  If the user decides to pair the device with a printer, the detail data will be printed once pairing is completed.

     

    An example image of the add item screen is shown below.

     

    Deatil.png

     

     

     

     

    Application Development

     

    Creating a new Android application in Eclipse is easy, with just a few button clicks and text entries a developer can have a working application in seconds; this is exactly how StockChecker was started.

     

    MainActivity

     

    The Eclipse wizard to create a new Android application produces a java file named MainActivity.java. In MainActivity.java the class MainActivity, the starting point for the application is defined, this class extends the class Android class ActionBarActivity.

     

    The wizard also creates a file called menu.xml  that defines a single item in the menu bar.  The definition if the item is shown in the XML excerpt below,  the item is hidden when the application runs by the line ‘app:showAsAction="never"’.  Changing the value of showAsAction to “always”, makes the item visible when the application runs.

     

        <item

            android:id="@+id/action_settings"

            android:orderInCategory="100"

            android:title="@string/action_settings"

    app:showAsAction="never"/>

     

    The stub method created by the wizard in MainActivity.java that is invoked when the menu is touched is shown below.  It can be seen that the id of the menu item that was tapped is passed as a parameter to this method.  The generated code contains a test to determine if the tapped item is the item “action_settings” defined in menu.xml.

     

        public boolean onOptionsItemSelected(MenuItem item) {

    // Handle action bar item clicks here. The action bar will

    // automatically handle clicks on the Home/Up button, so long

    // as you specify a parent activity in AndroidManifest.xml.

    int id = item.getItemId();

    if (id == R.id.action_settings) {

    return true;

    }

    return super.onOptionsItemSelected(item);

        }

     

    The power of the MenuBarActivity class as a menu system can be unlocked by adding just a few lines of java code.  In StockChecker, instead of simply returning “true” when an item on the menu is tapped, a new activity (screen) is started.

     

    Displaying the list of database items on the main screen is more complicated than menu navigation, however tools are provided by Android that significantly reduce the complexity.  In Android often a screen is represented by an activity.   Activities have a life cycle that is managed by the operating system, the creation and life cycle management of activities requires a certain amount of overhead.  There are times when it makes sense to use the Android concept of a Fragment to represent a screen or a portion of a screen.  This is the approach taken in StockChecker, the class ListManager was defined, extending the Android class ListFragment. The file list_row.xml was created to define the appearance of each item displayed in the list, using the drag and drop GUI tools in Eclipse.

    ListManger performs three basic functions, it displays items from the database, responds when an item in the list is tapped,  and monitors changes to the database.  Displaying the database is accomplished using an Android CursorAdapter.  The CursorAdapter is used here to associate fields from the database with the layout defined in list_row.xml.  The method onListItemClick is invoked when an item is tapped, starting the ProductDetail activity with a new Intent, the product code of the item is added to the Intent.   By implementing the callback interface LoaderManager.LoaderCallbacks<Cursor>, ListManger is able refresh the items displayed whenever the database changes.  An important thing to notice about all of the methods in ListManager is that they are preceded by the @Override annotation, meaning that the method name exists in either in the class that ListManager extends or by the interface that ListManager implements.  This means that the  Android developers anticipated the requirement for such functionality and built it into the framework. The CursorAdapter used by ListManger is called ButtonCursorAdapter, it was created to illustrate a simple mechanism for modifying the appearance of each item displayed, in this case alternating the shade of the background color.  A more thorough description of the code and concepts used in ListManger is not given here, but a review of the code shows that not very much is needed to get a lot of functionality.

     

    MainActivity performs the EMDK initialization and registers a BroadcastReceiver to be called when a barcode is read by the scanner. If the receiver is called, it starts the ProductDetail activity with a new Intent, the barcode obtained from the scanner is added to the Intent.  The EMDK profile manager wizard in Eclipse was used to create to create a profile for this application.  The profile defines the behavior for each activity in the application.

     

    In addition to initializing the EMDK MainActivity, initializes established contact with the database, and registers itself a messaging server.  The details of the database integration will not be covered here, some information about the messaging server will be included later.

     

     

    Product Detail/Add Item

     

    The product detail and add item screens are similar, and will be discussed together.  The product detail screen is defined in ProductDetail.java and product_detail.xml.  The add item screen is defined in BarcodeEntry.java and activity_barcode_entry.xml. 

     

    The primary class in ProductDetail.java is ProductDetail which extends the Android Activity class.  When ProductActivity is started, data retrieved from the Intent that started the Activity is used to search the database.  If the item being searched for is found, the data is displayed.

     

    One of the requested topics was managing the soft keyboard.   The add item activity (BarcodeEntry) shows how to lower the soft keyboard using a single Android function call, inputMethodManager.hideSoftInputFromWindow(barcode.getWindowToken(), 0). The variable barcode is an Android TextView object that represents the product code displayed on the screen.  This text entry field was chosen, since a search will be initiated after text is entered into this field using the soft keyboard, if the keyboard remained visible it would obscure the displayed data. By implementing an OnFocusChangeListener class, the activity can detect when input focus moves away from the text entry field, the implication is that when focus moves away from this field, the entry is complete and the database should be searched, in case the object already exists.  If the search is successful, the label on the button of the add item screen changes from “Add” to “Update”, using the setText method of the Android Button object.

     

    The ProductDetail activity has a button labeled “Print”, to send the displayed information to a Zebra Bluetooth printer.  If the print button is pressed, the application tries to determine if a printer is currently paired with the device.  If a printer is paired the application will simply try to send the data to the paired printed.  If a printer is not paired, the user will get the opportunity to pair their device with a printer.  Pairing can be done in two ways, scanning a barcode, or if the device has an NFC radio, by bringing the device in close proximity of an NFC tag on the Zebra printer.  Depending on the pairing method, a combination of EMDK, Android and Zebra APIs are used to pair the two devices.  The implementation details can be found in the files ProductDetail.java and PairActivity.java.

     

     

    Messaging/Notifications

     

    The screens/activities discussed so far have cover most of the topics that were requested in the workshop.  Two features that are related in the StockChecker application are notifications and messaging. Notifications in Android are messages that appear at the top of the screen.  When a notification first appears an icon can be displayed as a visual aid to the user indicating its origin.  These notifications can accumulate in a list that can be “pulled down” and viewed.  Notifications can optionally start an activity when tapped.  When the database that StockChecker uses is updated on the server, a message is sent to a messaging server, indicating a change has taken place.  An Android messaging client service is included with the StockChecker application that subscribes to update messages that are posted to the messaging server.  When the messaging client service receives a message, two things happen.  First, an Intent is Broadcast to the system using the Android method sendBroadcast. A receiver is defined in the manifest that listens for this Intent.  When the broadcast is received, a request is made to immediately synchronize the local database with the database on the server.  Second, a notification is delivered to the system that contains the contents of the message received from the messaging server.  During initialization StockChecker registers MainActivity with the client service, tapping a notification created by the client service will start or restore the MainActivity, bringing it to the foreground.  StockChecker and the back-end server are using MQTT for messaging.  StockChecker uses the code available from the Eclipse project (org.eclipse.paho.client.mqttv3), and the server uses Mosquitto from mosquito.org.  A separate article will appear soon describing the use of MQTT.  Because there was no internet access at the workshop location, a virtual containing the required back-end servers was prepared used in the workshop.

     

     

    Conclusion

     

    There was a lot of ground to cover in the two day workshop, but Android, provides a rich programming interface that does a lot of the hard work.  Adding scanning and printing are both relatively simply using the EMDK and Zebra SDK.