web-dev-qa-db-de.com

Senden einer Zeichenfolge über Bluetooth von einem PC als Client an ein Mobiltelefon als Server

Ich benötige Hilfe beim Übertragen eines Strings von einem PC auf ein Android= mobiles Gerät über Bluetooth. Das Android mobiles Gerät sollte als Server fungieren und die String-Nachricht anzeigen auf dem Bildschirm des Geräts Der PC, der der Client ist, sollte den String an das mobile Gerät senden.

Ich möchte, dass der Server auf die extrahierte Zeichenfolge reagiert (über Bluetooth übertragen). Dies bedeutet, dass der Server einerseits immer auf neue Zeichenfolgen warten muss, andererseits jedoch weiterhin in der Lage sein muss, auf diese Nachrichten zu reagieren (z. B. von einem Menü zum anderen zu navigieren).

Ich habe es versucht, indem ich BlueCove (2.1.1) als BluetoothStack (für das ich die JAR von BlueCove als Bibliothek zu beiden Projekten hinzufüge) in Kombination mit einem Beispiel für eine Server-Client-Kommunikation verwendet habe, die ich gefunden habe hier =.

Aktualisierung:

Aktualisierter Code vom Server dank user_CC unter Verwendung einer RFComm -Verbindung für den Server:

public class RFCommServer extends Thread{

//based on Java.util.UUID
private static UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");

// The local server socket
private BluetoothServerSocket mmServerSocket;

// based on Android.bluetooth.BluetoothAdapter
private BluetoothAdapter mAdapter;
private BluetoothDevice remoteDevice;

private Activity activity;

public RFCommServer(Activity activity) {
    this.activity = activity;
}

public void run() {
    BluetoothSocket socket = null;
    mAdapter = BluetoothAdapter.getDefaultAdapter();        

    // Listen to the server socket if we're not connected
    while (true) {

        try {
            // Create a new listening server socket
            Log.d(this.getName(), ".....Initializing RFCOMM SERVER....");

            // MY_UUID is the UUID you want to use for communication
            mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("MyService", MY_UUID);
            //mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); // you can also try using In Secure connection...

            // This is a blocking call and will only return on a
            // successful connection or an exception
            socket = mmServerSocket.accept();

        } catch (Exception e) {

        }

        try {
            Log.d(this.getName(), "Closing Server Socket.....");
            mmServerSocket.close();

            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams

            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();

            DataInputStream mmInStream = new DataInputStream(tmpIn);
            DataOutputStream mmOutStream = new DataOutputStream(tmpOut);

            // here you can use the Input Stream to take the string from the client whoever is connecting
            //similarly use the output stream to send the data to the client

            RelativeLayout layout = (RelativeLayout) activity.findViewById(R.id.relativeLayout_Layout);
            TextView text = (TextView) layout.findViewById(R.id.textView_Text);

            text.setText(mmInStream.toString());
        } catch (Exception e) {
            //catch your exception here
        }
    }
}

Code des SPP-Clients von hier :

/**
* A simple SPP client that connects with an SPP server
*/
public class SampleSPPClient implements DiscoveryListener{

//object used for waiting
private static Object lock=new Object();

//vector containing the devices discovered
private static Vector vecDevices=new Vector();

private static String connectionURL=null;

public static void main(String[] args) throws IOException {

    SampleSPPClient client=new SampleSPPClient();

    //display local device address and name
    LocalDevice localDevice = LocalDevice.getLocalDevice();
    System.out.println("Address: "+localDevice.getBluetoothAddress());
    System.out.println("Name: "+localDevice.getFriendlyName());

    //find devices
    DiscoveryAgent agent = localDevice.getDiscoveryAgent();

    System.out.println("Starting device inquiry...");
    agent.startInquiry(DiscoveryAgent.GIAC, client);

    try {
        synchronized(lock){
            lock.wait();
        }
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }


    System.out.println("Device Inquiry Completed. ");

    //print all devices in vecDevices
    int deviceCount=vecDevices.size();

    if(deviceCount <= 0){
        System.out.println("No Devices Found .");
        System.exit(0);
    }
    else{
        //print bluetooth device addresses and names in the format [ No. address (name) ]
        System.out.println("Bluetooth Devices: ");
        for (int i = 0; i <deviceCount; i++) {
            RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(i);
            System.out.println((i+1)+". "+remoteDevice.getBluetoothAddress()+" ("+remoteDevice.getFriendlyName(true)+")");
        }
    }

    System.out.print("Choose Device index: ");
    BufferedReader bReader=new BufferedReader(new InputStreamReader(System.in));

    String chosenIndex=bReader.readLine();
    int index=Integer.parseInt(chosenIndex.trim());

    //check for spp service
    RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(index-1);
    UUID[] uuidSet = new UUID[1];
    uuidSet[0]=new UUID("446118f08b1e11e29e960800200c9a66", false);

    System.out.println("\nSearching for service...");
    agent.searchServices(null,uuidSet,remoteDevice,client);

    try {
        synchronized(lock){
            lock.wait();
        }
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }

    if(connectionURL==null){
        System.out.println("Device does not support Simple SPP Service.");
        System.exit(0);
    }

    //connect to the server and send a line of text
    StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL);

    //send string
    OutputStream outStream=streamConnection.openOutputStream();
    PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
    pWriter.write("Test String from SPP Client\r\n");
    pWriter.flush();


    //read response
    InputStream inStream=streamConnection.openInputStream();
    BufferedReader bReader2=new BufferedReader(new InputStreamReader(inStream));
    String lineRead=bReader2.readLine();
    System.out.println(lineRead);


}//main

//methods of DiscoveryListener
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
    //add the device to the vector
    if(!vecDevices.contains(btDevice)){
        vecDevices.addElement(btDevice);
    }
}

//implement this method since services are not being discovered
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
    if(servRecord!=null && servRecord.length>0){
        connectionURL=servRecord[0].getConnectionURL(0,false);
    }
    synchronized(lock){
        lock.notify();
    }
}

//implement this method since services are not being discovered
public void serviceSearchCompleted(int transID, int respCode) {
    synchronized(lock){
        lock.notify();
    }
}


public void inquiryCompleted(int discType) {
    synchronized(lock){
        lock.notify();
    }

}//end method

}

Zum Testen benutze ich ein Galaxy Nexus (GT-I9250) mit der neuesten Android API.

Dank user_CC laufen Client und Server jetzt ohne Ausnahme. Leider kann der Client keine Verbindung zum Server herstellen (siehe Abbildung unten). Dies liegt daran, dass das connectionURL niemals gesetzt ist (daher springt es hier standardmäßig hinein if(connectionURL==null)).

Wie kann ich den Client-Code ändern, damit ich ihn tatsächlich mit dem Server verbinden kann? Ich brauche ein richtiges connectionURL in der folgenden Zeile:

StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL)

Bisher habe ich nur herausgefunden, dass ich irgendwie den ServiceRecord bekommen muss, leider ist dies auch nicht im Beispielcode von hier beschrieben.

enter image description here

22
Elementary

Sie müssen RFComm APIS verwenden, damit die Kommunikation funktioniert. Ich habe es geschafft, eine Klasse zu definieren, die ein Thread ist und als Server fungiert und auf Clientverbindungen wartet. Ich habe auch einige Kommentare für Sie zum Verständnis platziert.

    private class AcceptThread extends Thread {
    // The local server socket
    private BluetoothServerSocket mmServerSocket;

    public AcceptThread() {
    }

    public void run() {         
        BluetoothSocket socket = null;

                    BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();

        // Listen to the server socket if we're not connected
        while (true) {

            try {
                // Create a new listening server socket
                Log.d(TAG, ".....Initializing RFCOMM SERVER....");

                // MY_UUID is the UUID you want to use for communication
                mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);                    
                //mmServerSocket = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID);  you can also try using In Secure connection...

                // This is a blocking call and will only return on a
                // successful connection or an exception                    
                socket = mmServerSocket.accept();                   

            } catch (Exception e) {

            }

            try {
                Log.d(TAG, "Closing Server Socket.....";                    
                mmServerSocket.close();



                InputStream tmpIn = null;
                OutputStream tmpOut = null;

                // Get the BluetoothSocket input and output streams

                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();


                mmInStream = new DataInputStream(tmpIn);
                mmOutStream = new DataOutputStream(tmpOut); 

                // here you can use the Input Stream to take the string from the client whoever is connecting
                //similarly use the output stream to send the data to the client
            } catch (Exception e) {
                //catch your exception here
            }

        }
    }

}

Ich hoffe das hilft

Für Ihre andere Frage:

Die Angabe der javax.bluetooth.UUID auf dem Client (PC) sollte von der javax.bluetooth.UUID stammen

   uuidSet2[0] = new UUID("446118f08b1e11e29e960800200c9a66", false);

Java.util.UUID auf der Serverseite deklarieren (Android)

    UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");
7
user_CC

Ich bin kein Java Entwickler, aber ich hatte ein ähnliches Problem mit Mono für Android (c #)

Die UUID für SPP sollte "00001101-0000-1000-8000-00805F9B34FB" Sein.
Dies ist eine bekannte UID zur Identifizierung eines Bluetooth SPP-Adapters.

In meinem C # -Code sieht das so aus

private static UUID MY_UUID = UUID.FromString("00001101-0000-1000-8000-00805F9B34FB");

Ich vermute, Sie können Ihren Java Code auf etwas aktualisieren, wie:

new UUID("00001101-0000-1000-8000-00805F9B34FB", true);

Obwohl ich nicht sicher bin, welche Parameter diese Funktion akzeptiert, müssen Sie dies möglicherweise überprüfen.

Ich habe das Gerät Android als Client verwendet, aber die Informationen könnten für Sie von Nutzen sein.
also werde ich hier meinen c # code einfügen, den ich ursprünglich aus Java samples,
Sie sollten es also zurückübersetzen können:

btAdapter = BluetoothAdapter.DefaultAdapter;

btAdapter.CancelDiscovery(); //Always call CancelDiscovery before doing anything
remoteDevice = btAdapter.GetRemoteDevice(Settings["deviceaddress"].ToString());

socket = remoteDevice.CreateRfcommSocketToServiceRecord(MY_UUID);
socket.Connect();

Grundsätzlich bekomme ich den Standardadapter, brich alle laufenden Erkennungsvorgänge ab und erstelle dann einen Socket für das andere Gerät. In Ihrem Fall möchten Sie zuhören, anstatt eine Verbindung herzustellen, aber nur zu Ihrer Information.

Ich hoffe, es hilft, sorry, ich konnte Ihnen nicht mehr geben Java spezifische Informationen.

'Update:' Ich habe gerade ein kleines Beispiel in Java) gefunden, das mehr oder weniger der gleichen Methode folgt, die ich verwende: Probleme mit der Verbindung von Bluetooth SPP in Android?

2
TimothyP