# Bluetooth Verbindung zwischen 2 Handys



## Omi (25. Dez 2006)

Guten Tag.

Also erstmal zu mir, ich bin momentan dabei Java mir selbst anzueignen und ich denke ich mache auch schon Fortschritte. Nun wollte ich mal auch einen kleinen Exkurs in die J2ME Welt machen um Programme auch auf dem Handy zu besitzen. Der Umstieg war relativ einfach, dank der Ähnlichkeit zu Applets. Leichte Programme à la Squash oder Stein Schere Papier gegen den Computer sind ruck zuck fertig und einsetzbar, was mich schon ein wenig begeistert hehe.

Naja wie dem auch sei, wenn man so leichte Programme besitzt hatte ich die Idee diese einfach zu erweitern, so dass man nun nicht nur gegen Computer sondern auch gegen andere spielen kann! Bluetooth ist meiner Meinung nach hierfür das Ideale!

Nur hab ich jetzt schon eine ganze Weile herum gesucht und meistens nur Code Schnipsel oder bereits fertige Beispiele gefunden. Ich habe versucht diese nachzuvollziehen aber immer wenn ich gedacht hatte ich wüsste wie ich diese Beispiele selber anwenden könnte und umschreiben will, scheint irgendetwas nicht zu klappen.

Kennt irgendjemand ein Tutorial was einen Schritt für Schritt in die Bluetooth Technologie einführt (das von Sun hab ich bereits versucht, aber tut mir Leid.. das ist glaub ich für Menschen die schon Jahre lang Erfahrung haben :/). Oder kann mir jemand Fragen beantworten???


Zu den Fragen, nehmen wir dieses Codebeispiel, welches ich fand und mir am meisten bisher geholfen hatte, aber immer noch Rätsel aufschliesst. Es besteht auf 3 einfachen Dateien:



BluetoothEchoDemo.java:


```
import javax.bluetooth.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;

/**
 * A pretty straight-forward class with menu that allows you to invoke a bluetooth server or bluetooth client
 * In keeping this demo simple the remainder the program output is shown in the console area.
 *
 */
public final class BluetoothEchoDemo extends MIDlet implements CommandListener {
  
  // Shared UUID by server and client   
  public static final UUID RFCOMM_UUID = new UUID(0x0003);	
	
  // Soft-keys
  private final Command selectCmd = new Command("Select", Command.SCREEN, 2);
  private final Command exitCmd = new Command("Exit", Command.EXIT, 1);        

  // Menu
  private static final String[] menuLabels = { "Server", "Client" };    
  private final List menu = new List("Bluetooth Echo Demo", List.IMPLICIT, menuLabels, null);

  // Classes for Server and Client
  private EchoClient echoClient;
  private EchoServer echoServer;

  public BluetoothEchoDemo() {
    menu.addCommand(exitCmd);
    menu.addCommand(selectCmd);
    menu.setCommandListener(this);
  }

  public void startApp() {
    Display.getDisplay(this).setCurrent(menu);
  }

  protected void destroyApp(boolean unconditional) {
  }

  protected void pauseApp() {
  }

  public void commandAction(Command c, Displayable d) {
    if (c == exitCmd) {
      destroyApp(true);
      notifyDestroyed();
      return;
    }

    // Instantiate the select client type
    switch (menu.getSelectedIndex()) {
      case 0: {          
        echoServer = new EchoServer();
        break;
      }
        
      case 1: {
       echoClient = new EchoClient("Ein Test");
        break;
      }
      default: // this shouldn't occur
        break;
    };
  }  

 /**
  * @abstract to assemble the data in the given stream connection
  *           probably best to move this method to a common class
  *           
  * @param Stream Connection
  * @return data read through the stream as a string
  *
  */
  public final static String readData(StreamConnection conn) {
    
    InputStream input = null;
    byte[] data = null;   
    
    try {       	      	
      input = conn.openInputStream();
      
      // Probably want to throw an exception if length is not greater then 0
      int length = input.read();       
      data= new byte[length];
      length = 0;

      // Assemble data
      while (length != data.length) {     
        int ch = input.read(data, length, data.length - length);
        if (ch == -1) {
          throw new IOException("Can't read data");
        }
        length += ch;
      }      

    } catch (IOException e) {
      System.err.println(e);
    } finally {        
    	
      // close input stream	
      if (input != null) {
        try {
          input.close();
        } catch (IOException e) {
        }
      } 
    }
    return new String(data);       
  }   
}
```



EchoClient.java:

```
import javax.bluetooth.*;
import javax.microedition.io.*;
import java.io.*;

class EchoClient implements DiscoveryListener {
  private DiscoveryAgent discoveryAgent;
  private RemoteDevice[] remoteDevices;  
  private UUID[] uuidSet;  
  private String serviceUrl;
  private String message;

  
  public EchoClient() {
    try {
      LocalDevice localDevice = LocalDevice.getLocalDevice();
      discoveryAgent = localDevice.getDiscoveryAgent();  	      
      discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
    } catch (Exception e) {
      System.out.println(e);
    }
  }   
  
  public EchoClient(String msg)
  {
	  try {
		  this.message = msg;
	      LocalDevice localDevice = LocalDevice.getLocalDevice();
	      discoveryAgent = localDevice.getDiscoveryAgent();  	      
	      discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
	    } catch (Exception e) {
	      System.out.println(e);
	    }
  }

  public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
    try {
      // Get Device Info
      System.out.println("Device Discovered");
      System.out.println("Major Device Class: " + cod.getMajorDeviceClass() + " Minor Device Class: " + cod.getMinorDeviceClass());
      System.out.println("Bluetooth Address: " + btDevice.getBluetoothAddress());
      System.out.println("Bluetooth Friendly Name: " + btDevice.getFriendlyName(true));     
      
      // Search for Services
      uuidSet = new UUID[1];     
      uuidSet[0] = BluetoothEchoDemo.RFCOMM_UUID;      
      int searchID = discoveryAgent.searchServices(null,uuidSet,btDevice,this);      
    } catch (Exception e) {
      System.out.println("Device Discovered Error: " + e);	
    }
  }
  
  public void inquiryCompleted(int discType) {
    System.out.println("InquiryCompleted");
  }
  
  public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
    System.out.println("ServicesDiscovered");
    
    // in this example there is only one service
    for(int i=0;i<servRecord.length;i++) {       
       serviceUrl = servRecord[i].getConnectionURL(0,false);
    }    
  }  
  
  public void serviceSearchCompleted(int transID, int responseCode) {    
    
    if(responseCode == SERVICE_SEARCH_ERROR)
      System.out.println("SERVICE_SEARCH_ERROR\n");
       
    if(responseCode == SERVICE_SEARCH_COMPLETED) {
      System.out.println("SERVICE_SEARCH_COMPLETED\n");
      System.out.println("Service URL: " + serviceUrl);
      
      StreamConnection conn = null;
      try {
    	
        conn = (StreamConnection)Connector.open(serviceUrl);
        OutputStream output = conn.openOutputStream();         
        output.write(message.length());
        output.write(message.getBytes());
        output.close();        
        
        System.out.println(BluetoothEchoDemo.readData(conn));    
        
        
      } catch (Exception ex) {
      	System.out.println(ex);
      } finally {
    	  try {
          	  conn.close();
          	} catch (IOException ioe) {
          	  System.out.println("Error Closing connection " + ioe);
            }
      	
      }
    }
    
    if(responseCode == SERVICE_SEARCH_TERMINATED)
      System.out.println("SERVICE_SEARCH_TERMINATED\n");
    
    if(responseCode == SERVICE_SEARCH_NO_RECORDS)
      System.out.println("SERVICE_SEARCH_NO_RECORDS\n");

    if(responseCode == SERVICE_SEARCH_DEVICE_NOT_REACHABLE)
      System.out.println("SERVICE_SEARCH_DEVICE_NOT_REACHABLE\n");    
  } 
}
```


EchoServer.java:


```
import javax.bluetooth.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;

public class EchoServer implements Runnable {    
  StreamConnectionNotifier notifier;
  StreamConnection conn;
  LocalDevice localDevice;
  ServiceRecord serviceRecord;
  InputStream input;
  OutputStream output;
  
  private boolean isInit;  
  private static String serverUrl = "btspp://localhost:" + BluetoothEchoDemo.RFCOMM_UUID + ";name=rfcommtest;authorize=true";
  
  public EchoServer() { 	 
    isInit = false;    
    Thread thread = new Thread(this);
    thread.start();
  }
  
  public void run() {
    if (!isInit) {
      // Initialization is done in the thread to avoid dead lock 'isInit' ensures it is done once only
      try {
        conn = null;
        localDevice = LocalDevice.getLocalDevice();
        localDevice.setDiscoverable( DiscoveryAgent.GIAC );              
        notifier = (StreamConnectionNotifier)Connector.open(serverUrl);      
      } catch (BluetoothStateException e) {        
        System.err.println( "BluetoothStateException: " + e.getMessage() );    
      } catch (IOException e) {        
        System.err.println( "IOException: " + e.getMessage() );      
      }          
      isInit=true;
      System.out.println( "Starting Echo Server" );     	      
    }
    
    // 
    try {
      System.out.println("\n\nServer Running...");
      
      // Pauses thread until Transmission occurs
      conn = notifier.acceptAndOpen();            

      // Read Data Transmission
      String msg = BluetoothEchoDemo.readData(conn);        
      System.out.println("Received Message from Client: " + msg);

      // Send Back a Message
      msg = "Hello Back from Server";        
      output = conn.openOutputStream();       
      output.write(msg.length()); // length is 1 byte
      output.write(msg.getBytes());
      output.close();                    
    } catch (Exception ex) {
      System.err.println("Bluetooth Server Running Error: " + ex);	
    }    
  } 
  
}
```












So nun zu meinen Fragen:
Dieses "einfache" Bluetooth Programm baut eine Verbindung zwischen Server und Client auf und sendet dann jeweils an beide eine Nachricht vom anderen. Eigentlich genug um darauf aufzubauen um zum Beispiel das Ergebnis bei einem Stein Schere Papier mit dem anderen abzugleichen. Jedoch frag ich mich, wie ich nach dem Aufbau der Verbindung weiterhin Nachrichten verschicken kann! Ist das möglich? Oder muss erneut eine Verbindung erstellt werden? Tut mir Leid für diese wahrscheinlich sehr sehr dummen Fragen, aber ich finde einfach kein Tutorial und kenne auch keinen Menschen der sonst Java kann .
Hoffe es kann mir jemand helfen.

mfg
Domi


----------



## Omi (26. Dez 2006)

Hi also ich hab mich nochmal weiter intensiv mit dem Thema beschäftigt und weiss jetzt schon warum man alles macht und was dabei passiert. Also bei der suche nach Devices und bei der suche nach weiteren Services. Nur ist mein einziges Problem jetzt der Stream der zwischen den beiden läuft!

Wie kann ich nach dem Daten hin und her geschcikt wurden, bei Aufruf von einen der beiden Seiten nochmal etwas über ihn schicken? Ich habs einfach mal probiert indem ich nochmal sagte:


```
output = conn.openOutputStream();       
      output.write(msg.length()); // length is 1 byte
      output.write(msg.getBytes());
      output.close();
```

Aber dann kommt immer "no more output streams". ? Ich hab ehrlich nicht so die Ahnung was ein Stream ist, ich stell es mir so wie eine Rohrleitung vor die nur in eine Richtung geht. Und die StreamConnection ist dann einfach 2 Rohrleitungen nebeneinander die dann sozusagen zwischen Client und Server existiert. Kann mir hierbei jemand helfen?


----------



## Omi (27. Dez 2006)

habs selbst geschafft.. falls es jemand hier trotzem gelesen haben sollte... thx trotzdem


----------



## SaschaLR (12. Mrz 2007)

Und wie sieht deine Lösung aus?


----------



## geisi (26. Mrz 2007)

wenn ich dein midlet starte, dann funktioniert es nur, wenn server und client auf dem gleichen gerät sind.
wie muss ich deinen code umschreiben, damit es zwischen zwei verschieden geräten funktioniert.

habe nämlich dein midlet 2 mal mit dem emulator auf dem laptop gestartet - funktioniert hervoragend
wenn ich aber den client auf dem handy und den server auf dem emulator(laptop) laufen lasse, findet er den server nicht. 

danke im voraus


----------



## kyuhwa (30. Apr 2007)

Hey,
danke für das Beispiel. Habe lange mit der Bluetoothdemo aus dem WirelessToolkit rumgespielt und bin zu keinem Ergebnis gekommen.
Dein Beispiel hat mir echt geholfen .


----------

