The IncomingEventForm
class contains a Form
that is displayed when an event message is received.
It opens a message connection, decodes the message, and extracts the
event information from the message. The event title and time as well
as the sender are then displayed in the Form
on the
screen.
To implement the IncomingEventForm
class:
Create the IncomingEventForm.java
class file.
Import the required
packages, initialize the UI elements and Commands
, and create a CommandListener
.
import java.io.*; import java.util.*; import javax.microedition.lcdui.*; import javax.microedition.pim.*; import javax.wireless.messaging.*; // Forms displayed when a message is received class IncomingEventForm extends Form implements CommandListener { private Command acceptCommand, exitCommand, backCommand; private TextField number, duration, topic; private DateField dateTime; private final EventSharingMIDlet parent; private Event event; IncomingEventForm(EventSharingMIDlet parent, BinaryMessage msg) { super("Event Received"); this.parent = parent; backCommand = new Command("Back", Command.BACK, 2); exitCommand = new Command("Exit", Command.EXIT, 2); addCommand(backCommand); addCommand(exitCommand); setCommandListener(this); parent.enqueueOperation(new LoadEvent(msg)); } public void commandAction(Command cmd, Displayable displayable) { if (cmd == acceptCommand) { // insert the event in a different thread parent.enqueueOperation(new InsertEvent()); } else if (cmd == exitCommand) { parent.notifyDestroyed(); } else if (cmd == backCommand) { parent.showMain(); } }
Create a method for searching through the contacts lists. The actual search functionality is implemented in the next step.
// finds a name based on the number in all contact lists private String findName(String number) { String[] allLists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST); if (allLists.length > 0) { String results[] = new String[allLists.length]; for (int i = 0; i < allLists.length; i++) { results[i] = findNameInList(number, allLists[i]); } // if there is more than one, only the first is returned for (int i = 0; i < allLists.length; i++) { if (results[i] != null) { return results[i]; } } } return null; }
Create a method for finding the searched entry from the contacts list. The method is called separately for every contacts list.
// finds a name based on the number in a particular contact list // if for some reason it cannot be found, return null private String findNameInList(String number, String list) { ContactList contactList = null; try { contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY, list); if (contactList.isSupportedField(Contact.TEL) && contactList.isSupportedField(Contact.FORMATTED_NAME)) { Contact pattern = contactList.createContact(); pattern.addString(Contact.TEL, PIMItem.ATTR_NONE, number); Enumeration matching = contactList.items(pattern); if (matching.hasMoreElements()) { // will only return the first match Contact ci = (Contact) matching.nextElement(); // FORMATTED_NAME is mandatory return ci.getString(Contact.FORMATTED_NAME, 0); } } } catch (PIMException e) { // just ignore and return null; } catch (SecurityException e) { // just ignore and return null; } finally { if (contactList != null) { try { contactList.close(); } catch (PIMException e) { // ignore, nothing can be done here } } } return null; }
Create an inner class for inserting the event into the local database. Verify that the relevant fields are supported, and display a message to the user if no event list is found.
private class InsertEvent implements Operation { public void execute() { EventList eventList = null; try { PIM pim = PIM.getInstance(); String listNames[] = pim.listPIMLists(PIM.EVENT_LIST); if (listNames.length > 0) { eventList = (EventList) pim.openPIMList(PIM.EVENT_LIST, PIM.READ_WRITE, listNames[0]); // Check that the fields are supported if (eventList.isSupportedField(Event.SUMMARY) && eventList.isSupportedField(Event.START) && eventList.isSupportedField(Event.END)) { // event cannot be null at this stage eventList.importEvent(event).commit(); parent.showMessage("Event inserted in the local database"); } } else { parent.showMessage("No Event list found"); } } catch (PIMException e) { parent.showMessage(e.getMessage(), IncomingEventForm.this); } catch (SecurityException e) { parent.showMessage(e.getMessage(), IncomingEventForm.this); } finally { if (eventList != null) { try { eventList.close(); } catch (PIMException e) { // nothing to do here, just ignore } } } } }
Create an inner
class for decoding the message. The address is parsed to extract the
phone number. The appropriate data is extracted from the message,
and the fields in the Form
are updated with the information.
// This operations reads an event from a TextMessage private class LoadEvent implements Operation { private final BinaryMessage msg; LoadEvent(BinaryMessage msg) { this.msg = msg; } public void execute() { PIMItem items[] = null; try { items = PIM.getInstance().fromSerialFormat(new ByteArrayInputStream(msg.getPayloadData()), "UTF-8"); } catch (PIMException e) { parent.showMessage(e.getMessage(), IncomingEventForm.this); } catch (UnsupportedEncodingException e) { // should not happen since UTF-8 is mandatory } if (items != null && items.length > 0) { // let's assume that only one event // was contained in the message event = (Event) items[0]; // Sanity check int summaryCount = event.countValues(Event.SUMMARY); int startCount = event.countValues(Event.START); int endCount = event.countValues(Event.END); if (summaryCount > 0 && startCount > 0 && endCount > 0) { topic = new TextField("topic", event.getString(Event.SUMMARY, 0), 24, TextField.ANY); String source = msg.getAddress(); // assume the message starts with sms:// and has a port number String phoneNumber = source.substring(6, source.lastIndexOf(':')); String sourceName = findName(phoneNumber); if (sourceName != null) { number = new TextField("From", sourceName, 20, TextField.ANY | TextField.UNEDITABLE); } else { number = new TextField("From", phoneNumber, 20, TextField.PHONENUMBER | TextField.UNEDITABLE); } long startDate = event.getDate(Event.START, 0); long length = event.getDate(Event.END, 0) - startDate; // get the length in minutes length /= 60000; dateTime = new DateField("on", DateField.DATE_TIME, TimeZone.getDefault()); dateTime.setDate(new Date(startDate)); duration = new TextField("duration (min)", "" + length, 24, TextField.ANY); append(number); append(topic); append(dateTime); append(duration); acceptCommand = new Command("Accept", Command.OK, 1); addCommand(acceptCommand); } else { append(new StringItem("", "Incoming event was incomplete")); } } else { event = null; acceptCommand = null; append(new StringItem("", "Error during message decoding")); } } } }
Now that you have handled incoming events, implement the error screen.