/* * Copyright © 2013 Nokia Corporation. All rights reserved. * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. * Oracle and Java are trademarks or registered trademarks of Oracle and/or its * affiliates. Other product and company names mentioned herein may be trademarks * or trade names of their respective owners. * See LICENSE.TXT for license information. */ package com.nokia.example.bcexchanger; import java.util.Vector; import javax.microedition.midlet.MIDlet; import javax.microedition.midlet.MIDletStateChangeException; import com.nokia.example.bcexchanger.comm.ExchangeListener; import com.nokia.example.bcexchanger.comm.ExchangerComm; import com.nokia.example.bcexchanger.comm.ExchangerCommImpl; import com.nokia.example.bcexchanger.ui.AddressBookScreen; import com.nokia.example.bcexchanger.ui.AlertMessage; import com.nokia.example.bcexchanger.ui.MainScreen; import com.nokia.example.bcexchanger.ui.ProgressScreen; import com.nokia.example.bcexchanger.ui.Screen; import com.nokia.example.bcexchanger.ui.ServiceListScreen; /** * * 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 * communication 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); public static final int ERROR_ALERT_MESSAGE_TIMEOUT = 3000; /** * 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 } } /** * 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 service chosen by the user */ public void serviceSelected(int index) { selectedServiceIndex = index; } /** * Initializes 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); initComm(); } } 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 { // Unknown 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 choice 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); } /** * This is a helper methods 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(int errorType) { if (errorType == ExchangeListener.ERROR_BUETOOTH_OFF) { changeScreen(new AlertMessage(this, "Please turn on bluetooth and try again. Application will exit")); } else { changeScreen(new AlertMessage(this, "Fatal Bluetooth error. Application will exit")); } try { Thread.sleep(ERROR_ALERT_MESSAGE_TIMEOUT); } catch (InterruptedException ex) { } quit(); } /** * Called in case of problems with buetooth server (SecurityException) * */ public void onSecurityError() { changeScreen(new AlertMessage(this, "Application not authorized to access the restricted API. Application will exit")); try { Thread.sleep(ERROR_ALERT_MESSAGE_TIMEOUT); } catch (InterruptedException ex) { } quit(); } }