One of my current tasks is the development of the MeshMS Gateway application. The purpose of the application is to relay MeshMS messages that are being distributed via Rhizome on a Serval Project mesh network to another network or device. In this first instance MeshMS messages will be relayed over a satellite connection.
A key component of the application is restricting the destination phone numbers that messages will be relayed for. My solution was to use a database table to list the phone numbers and provide a user interface for the user to add and remove entries. The final UI looks like this:

Screenshot of the UI showing a populated ListView
It is implemented in the RelayNumbers activity.
My google-fu was letting me down yesterday. All I could find were examples of populating a ListView using an array of items, or examples of using custom layouts with a Cursor in a ListView. Neither of these were what I needed.
The solution came when I discovered that Android ships with a number of simple built in layouts for use with ListViews. The are referenced via the android.R.layout class and the XML for the layouts are stored in the following directory:
{android-sdk}/platforms/{platform-version}/data/res/layout
Using a cursor with a ListView is a multi stage process.
The first stage is getting the data that will be used to populate the ListView. For example this is implemented in my activity like this:
ContentResolver mContentResolver = getContentResolver();
Cursor mCursor = mContentResolver.query(GatewayItemsContract.Contacts.CONTENT_URI, null, null, null, null);
startManagingCursor(mCursor);
This is standard code for creating a cursor in an activity. The only item specific to my code is the
GatewayItemsContract
class which specifies the attributes of the data in my content provider.
The next task is to add the cursor to a SimpleCursorAdapter. This class maps data in the cursor to items in the layout. In my activity the code looks like this:
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_single_choice,
mCursor,
new String[] {GatewayItemsContract.Contacts.Table.PHONE_NUMBER},
new int[] { android.R.id.text1});
The key elements here are:
- The use of the provided layout for a list with a single item associated with an option button on line 2
- The mapping between the database field in cursor as identified on line 4 and the component of the view as identified on line 5
Once the SimpleCursorAdapter is configured it is necessary to associate it with the ListView using code like this:
contactList.setAdapter(mAdapter);
contactList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Now when the ListView is displayed the content in the identified field is mapped to the identified element in the ListView and the user can select only one item at a time with a visual indication of which item is selected.
The last two components are to use a custom OnItemClickListener to capture the touch on the selected item and store it for later processing by the method behind the Delete Contact button.
// capture touches on the listview
contactList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// store the selected contact for later
TextView textView = (TextView) view;
contactToDelete = textView.getText().toString();
}
});
And clear the selected item index using the clearChoices() method when the actual item is deleted so that the item immediately below the one that was deleted isn’t automatically selected when the data in the cursor refreshes.
contactList.clearChoices();
For a full code listing please take a look at the RelayNumbers activity.