www.pudn.com > Bluegammon蓝牙的应用编程.rar > BluetoothClientWorkflow.java


// Copyright (c) 2005 Sony Ericsson Mobile Communications AB 
// 
// This software is provided "AS IS," without a warranty of any kind.  
// ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,  
// INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A  
// PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.  
// 
// THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se) 
 
package bluegammon.gui; 
 
import java.io.IOException; 
 
import javax.bluetooth.BluetoothStateException; 
import javax.bluetooth.DeviceClass; 
import javax.bluetooth.DiscoveryAgent; 
import javax.bluetooth.DiscoveryListener; 
import javax.bluetooth.LocalDevice; 
import javax.bluetooth.RemoteDevice; 
import javax.bluetooth.ServiceRecord; 
 
import bluegammon.Bluegammon; 
import bluegammon.Resources; 
import bluegammon.gui.menu.ItemAction; 
import bluegammon.gui.menu.MenuPage; 
import bluegammon.gui.menu.PageItem; 
import bluegammon.gui.popup.Popup; 
import bluegammon.gui.popup.PopupListener; 
import bluegammon.io.BackgammonBTConnection; 
import bluegammon.io.BackgammonConnection; 
 
 
/** 
 * Handles the different steps of connecting to a server 
 * as a client. Controls the gui component, the  
 * BluetoothDevicePage 
 *  
 * @see bluegammon.gui.BluetoothDevicePage 
 * @author Peter Andersson 
 */ 
public class BluetoothClientWorkflow implements ItemAction, DiscoveryListener, PopupListener 
{ 
  /** The page we add found device items to */ 
  protected BluetoothDevicePage m_devicePage; 
  /** Reference to popup we need to close on successful connection */ 
  protected Popup m_popup; 
  /** The connection */ 
  protected BackgammonConnection m_clientConnection = null; 
  /** Page item property key identifying the remote device */ 
  protected static final int REMOTE_DEVICE = 100; 
   
  /** 
   * Creates a workflow for connecting to a server as client. Uses 
   * the specified device page as a gui component. 
   * @param devicePage	The gui component of this workflow. 
   */ 
  public BluetoothClientWorkflow(BluetoothDevicePage devicePage) 
  { 
    m_devicePage = devicePage; 
  } 
   
  /** 
   * Refreshes the view of nearby devices.  
   */ 
  public synchronized void refresh() 
  { 
    if (!m_devicePage.isSearching()) 
    { 
      m_devicePage.removeAllItems(); 
      DiscoveryAgent discoveryAgent; 
      try 
      { 
        discoveryAgent = LocalDevice.getLocalDevice().getDiscoveryAgent(); 
        discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this); 
        m_devicePage.setSearching(true); 
      } 
      catch (BluetoothStateException e) 
	  { 
        searchingStopped(); 
        e.printStackTrace(); 
        Bluegammon.showPopup((Resources.getString(Resources.TXT_BT_DISC_FAIL) + 
            "\n" + e.getMessage()).toCharArray(), 
            Popup.ALT_OK, 10, 0, 0, null); 
	  } 
    } 
  } 
   
 
  /** 
   * Called when all nearby devices has been found or 
   * an error occurred during search. 
   */ 
  public void searchingStopped() 
  { 
    m_devicePage.setSearching(false); 
    if (m_devicePage.size() == 0) 
    { 
      Bluegammon.showPopup(Resources.getChars(Resources.TXT_BT_NO_DEVICES), 
          Popup.ALT_OK, 60,0,0, null); 
    } 
  } 
 
  /** 
   * Called when user selects an item in a page. This 
   * item can be that user wants to see list of devices 
   * to connect to, or the actual device item to connect to. 
   *  
   * @param page	The page this action is called from. 
   * @param item	The item this action is called from. 
   */ 
  public void itemAction(MenuPage page, PageItem item) 
  { 
    Object rDevObj = item.getProperty(REMOTE_DEVICE); 
    if (rDevObj != null) 
    { 
      // User has selected a device to connect to 
      RemoteDevice rDev = (RemoteDevice)rDevObj; 
      connectTo(rDev, item.getLabel()); 
    } 
    else 
    { 
      // User is moving to the page displaying all nearby 
      // devices, start a refresh if view is empty 
      if (!m_devicePage.isSearching() && m_devicePage.size() == 0) 
      { 
        refresh(); 
      } 
    } 
  } 
   
  /** 
   * Called when user presses cancel during connection to server. 
   */ 
  public void selectedChoice(byte choice, boolean timeOut) 
  { 
    Popup p = Bluegammon.getCurrentPopup(); 
    if (p != null) p.dispose(); 
    BackgammonConnection bgconn = null; 
    synchronized(this) 
    { 
      bgconn = m_clientConnection; 
    } 
    if (bgconn != null) 
    { 
      try 
      { 
        bgconn.close(); 
      } catch (IOException e) {} 
    } 
  } 
   
  /** 
   * Connects to a remote server. 
   * @param rDev	The remote device running the server. 
   * @param name	The name of the remote device. 
   */ 
  protected void connectTo(RemoteDevice rDev, char[] name) 
  { 
    m_popup = Bluegammon.showPopup((Resources.getString(Resources.TXT_BT_CONNECT) + 
        " " + new String(name) + "...").toCharArray(), 
        Popup.ALT_CANCEL, 0, 0, 0, this); 
    synchronized (this) 
    { 
      if (m_clientConnection == null) 
        m_clientConnection = new BackgammonBTConnection(); 
    } 
    try 
    { 
      if (!m_clientConnection.connectClient(rDev)) 
      { 
        Bluegammon.showPopup(Resources.getChars(Resources.TXT_BT_NONSERVER), 
            Popup.ALT_OK, 60, 0, 0, null); 
      } 
      else 
      { 
        if (m_popup != null) 
        { 
          m_popup.dispose(); 
          m_popup = null; 
        } 
        char[] localName = Resources.getChars(Resources.TXT_BT_UNKNOWN); 
        try 
        { 
          localName = LocalDevice.getLocalDevice().getFriendlyName().toCharArray(); 
        } catch (Throwable t) {} 
        Bluegammon.setBackgammonConnection(m_clientConnection); 
        Bluegammon.startRemoteGame(false, localName); 
      } 
    } 
    catch (IOException e) 
    { 
      m_popup = null; 
      Bluegammon.showPopup((Resources.getString(Resources.TXT_BT_CONN_FAIL) + "\n" +  
          e.getMessage()).toCharArray(), 
          Popup.ALT_OK, 60, 0, 0, null); 
      e.printStackTrace(); 
      try 
      { 
        m_clientConnection.close(); 
      } catch (IOException e1) {} 
    } 
  } 
 
  // DiscoveryListener implementation 
 
  // See interface javadoc 
  public synchronized void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) 
  { 
    // Try to find the name of the device 
    char[] name = Resources.getChars(Resources.TXT_BT_UNKNOWN); 
    try 
    { 
      String nameStr = btDevice.getFriendlyName(false); 
      if (nameStr != null) 
      { 
        name = nameStr.toCharArray(); 
      } 
    } 
    catch(Throwable t) {} 
     
  	PageItem devItem = new PageItem(name, null, this, null); 
  	devItem.setProperty(REMOTE_DEVICE, btDevice); 
  	m_devicePage.addItem(devItem); 
  } 
 
  // See interface javadoc 
  public void inquiryCompleted(int discType) 
  { 
    searchingStopped(); 
  } 
   
  // See interface javadoc 
  public void servicesDiscovered(int transID, ServiceRecord[] records) 
  {} 
 
  // See interface javadoc 
  public void serviceSearchCompleted(int transID, int respCode) 
  {} 
}