I need help by transferring a string from a PC to an Android mobile device via Bluetooth. The Android mobile device should act as a server and displays the string message on the screen of the device. The PC which is the client should send the string to the mobile device.
I want the server react on the extracted string (transferred via Bluetooth). That means that on one side the server always has to listen for new strings to arrive, but on the other side still has to be able to react on these messages (e.g. navigate from one menu to another).
I tried it by using BlueCove (2.1.1) as BluetoothStack (for which I add the jar from BlueCove as a library to both projects) in combination with an example for a server-client communication that I found here.
Updated code from server thanks to user_CC using a RFComm
connection for the 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 of the SPP Client from here:
/** * 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 }
For testing I use a Galaxy Nexus (GT-I9250) with the latest Android API.
Thanks to user_CC, the client and server now runs without an exception. But sadly the client is not able to connect to the server (see the screenshot below). It is because the connectionURL
is never set (thus it jumps in here if(connectionURL==null)
by default.
How can I change the client code, so that I actually can connect it with the server? I need a proper connectionURL
in the following line:
StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL)
So far I only found out that I somehow need to get the ServiceRecord
, sadly this is also not described in the example code from here.
Pairing Two Devices via Bluetooth Setting up a Bluetooth devices involves first “pairing” the two devices and establishing a connection. The Bluetooth Client component sends the connection request and the Bluetooth Server component accepts the request.
Using messages, a Bluetooth mesh network communicates via a client-server architecture. The function of a server is to expose the states of an element.
You will need to use the RFComm APIS to make the communication work I have managed to define a class which is a Thread and will be acting as a server and listening for client connections. I have also placed some comments for you to understand.
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 } } } }
I hope this helps
For your another question:
Declaring javax.bluetooth.UUID on Client side (PC) UUID class should be from javax.bluetooth.UUID
uuidSet2[0] = new UUID("446118f08b1e11e29e960800200c9a66", false);
Declaring java.util.UUID at Server Side (Android)
UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With