Implementing the main MIDlet

BCExchanger class

This is the main application class which extends a MIDlet class. It serves as a parent to UI states (package bcexchanger.ui) and listens to communication events by implementing the ExchangeListener interface.

To create the class:

  1. Create the BCExchangerMIDlet class file.

  2. Assign the class to the bcexchanger package and import the required classes.

    package bcexchanger;
    
    import java.util.Vector;
    
    import javax.microedition.midlet.MIDlet;
    import javax.microedition.midlet.MIDletStateChangeException;
    
    import bcexchanger.comm.ExchangeListener;
    import bcexchanger.comm.ExchangerComm;
    import bcexchanger.comm.ExchangerCommImpl;
    import bcexchanger.ui.AddressBookScreen;
    import bcexchanger.ui.AlertMessage;
    import bcexchanger.ui.MainScreen;
    import bcexchanger.ui.ProgressScreen;
    import bcexchanger.ui.Screen;
    import bcexchanger.ui.ServiceListScreen
  3. Set the class to extend MIDlet and to implement ExchangeListener. Activate and display the UI screen.

    /**
     * 
     * This is the main application class which extends MIDlet class. It
     * serves as a parent to UI states (package example.BCExchanger.ui)
     * and listens to communicational events by implementing
     * ExchangeListener interface
     * 
     * @see example.BCExchanger.comm.ExchangeListener
     */
    public class BCExchangerMIDlet extends MIDlet
        implements ExchangeListener {
    
      private boolean commIsInitialized = false;
      private ExchangerComm comm;
      private int selectedServiceIndex;
      private MainScreen scr = new MainScreen(this);
      
      /**
       * Constructor
       */
      public BCExchangerMIDlet() { }
    
      /**
       * Changes the current UI screen
       * <p>
       * This method is used to display and make active a UI screen
       * 
       * @param screen -
       *          UI screen to display
       * @see example.BCExchanger.ui.Screen
       */
      public void changeScreen(Screen screen) {
        screen.makeActive();
      }
    
      /**
       * Called to force termination of MIDlet
       */
      public void quit() {
        if (comm != null) {
          comm.cancelWaiting();
        }
    
        try {
          destroyApp(true);
          notifyDestroyed();
        } catch (MIDletStateChangeException e) {
          // Ignore, we are closing anyways
        }
      }
    
  4. Implement a method for saving the index of a chosen service.

    Initialize the communication module.

    
      /**
       * Saves the index of the service of choice
       * <p>
       * This method is used in case several services are found during
       * service discovery In this case the ServiceListScreen is displayed
       * and on user selection this method is called to save the index of
       * the service of choice.
       * 
       * @param index -
       *          index of the serivice chosen by the user
       */
      public void serviceSelected(int index) {
        selectedServiceIndex = index;
      }
    
      /**
       * Intitializes the communication module
       */
      public void initComm() 
      {
        if (!commIsInitialized) { // avoid double initializing
          comm = new ExchangerCommImpl(this);
          commIsInitialized = true;
        }
      }
    
      /**
       * Getter method for Exchanger - class representing communication
       * module
       * 
       * @return a class implementing ExchangerComm interface,
       *         representing communication module
       */
      public ExchangerComm getExchanger() {
        return comm;
      }
    
      protected void destroyApp(boolean arg0)
          throws MIDletStateChangeException {}
    
      protected void startApp() throws MIDletStateChangeException {
        // ensure that we have own business card selected
        String uid = null;
        try {
          uid = Storage.getBCUID();
        } catch (Exception e) {
          changeScreen(new AlertMessage(this,
              "Cannot use the persistent storage. Application will exit"));
          return;
        }
    
        if (uid == null) {
          // if the MIDlet has not been started before
          // and own business card has not been chosen
          changeScreen(new AddressBookScreen(this));
        } else {
          changeScreen(scr);
        }
      }
    
      protected void pauseApp() {}
    
      public void onInquiryComplete(int code) {
        if (code == ExchangerComm.DONE) {
          String text = "Searching for Business Card Exchange service...";
          changeScreen(new ProgressScreen(this, text));
        } else if (code == ExchangerComm.ERROR) {
          changeScreen(new AlertMessage(this, "Errors during inquiry",
             scr));
        } else if (code == ExchangerComm.CANCELED) {
          changeScreen(new AlertMessage(this, "Inquiry is canceled",
              scr));
        } else {
          // unknwon error
          throw new RuntimeException("Internal error #26");
        }
    
      }
    
      public void onServiceDiscoveryComplete(int code) 
      {
        if (code == ExchangerComm.DONE) 
        {
          String text = "Sending own business card...";
          changeScreen(new ProgressScreen(this, text));
        }
        else if (code == ExchangerComm.NO_RECORDS) {
          changeScreen(new AlertMessage(
              this,
              "Cannot find Business card exchange service on the devices",
              scr));
        } else if (code == ExchangerComm.ERROR) {
          changeScreen(new AlertMessage(this,
              "Errors during service discovery", scr));
        } else if (code == ExchangerComm.CANCELED) {
          changeScreen(new AlertMessage(this,
              "Service discovery is canceled",scr));
        } else {
          // unknown error
          throw new RuntimeException("Internal error #27");
        }
      }
    
      public synchronized int resolveMultipleServices(Vector friendlyNames) throws InterruptedException {
        changeScreen(new ServiceListScreen(this, friendlyNames));
    
        wait(); // wait until the choise is made
    
        return selectedServiceIndex;
    
      }
    
      public byte[] getOwnBC() throws Exception {
        byte[] vCard = null;
        String uid;
        try {
          uid = Storage.getBCUID();
          vCard = AddressBook.getVCard(uid);
        } catch (Exception e) 
        {
          throw new Exception("getOwnBC did not succeed");
        }
        return vCard;
      }
    
      public void onSendComplete(int code) {
    
        if (code == ExchangerComm.DONE) {
          String text = "Send was successful!";
          changeScreen(new AlertMessage(this, text,
                  scr));
        } else if (code == ExchangerComm.CANCELED) {
          changeScreen(new AlertMessage(this, "Send is canceled ",
              scr));
        } else { // error
        	
          changeScreen(new AlertMessage(this, "Errors during sending ",
        		 scr ));
        }
      }
    
    
      public void onReceiveComplete(int code) {
        if (code == ExchangerComm.DONE) {
          changeScreen(new AlertMessage(this, "Receiving was successful!",
              scr));    	
        } else if (code == ExchangerComm.CANCELED) {
          changeScreen(new AlertMessage(this, "Receiving is canceled ",
              scr));
        } else { // error
          changeScreen(new AlertMessage(this, "Errors during receiving ",
              scr));
        }
      }
    
      public void onReceiveBC(byte[] vCard) throws Exception {
       AddressBook.setVCard(vCard);
      }
    
  5. Implement a helper method for unblocking any waiting code.

    
      /**
       * This is a helper method which unblocks waiting code in
       * resolveMultipleServices()
       */
      public synchronized void unblock() {
        notify(); // let resolveMultipleServices complete
      }
    
      public void onGetComplete(int code) {
    
      }
    
      public void onPutComplete(int code) {
    
      }
    
      /**
       * Called in case of problems with Bluetooth OBEX server accepting connection
       * 
       */
      public void onServerError() {
        changeScreen(new AlertMessage(this,
        "Fatal Bluetooth error. Application will exit"));
        return;
      }
    
    }