100 likes | 212 Views
Working with the Bluetooth radio. Nilanjan Banerjee. University of Arkansas Fayetteville, AR n ilanjan.banerjee@gmail.com. Mobile Systems Programming. How does the Bluetooth protocol work?. Scanning for other BT Devices --- inquiry scan Followed by page scan. Take about 15-20 seconds.
E N D
Working with the Bluetooth radio Nilanjan Banerjee University of Arkansas Fayetteville, AR nilanjan.banerjee@gmail.com Mobile Systems Programming
How does the Bluetooth protocol work? Scanning for other BT Devices --- inquiry scan Followed by page scan. Take about 15-20 seconds discovery Authentication process where two devices exchange a pin. Once paired the info is maintained in service discovery db pairing Service Discovery Every server device publishes a set of service that client connect to After pairing the devices communicate amongst each other over a RF communication channel RFComm
Android implementation overview? Access to the local Bluetooth device and its properties BluetoothAdapter Access to any Bluetooth device (usually remote) BluetoothDevice Socket interface for the server-end BluetoothServerSocket Socket interface for the client-end BluetoothSocket
Bluetooth Permissions • Permission BLUETOOTH is used ONLY for communication • Requesting a connection, accepting a connection, and transferring data • Permission BLUETOOTH_ADMIN is used for controlling the device • Device discovery, changing the settings of the Bluetooth device etc. <manifest> <uses permission android:name=“android.permission.BLUETOOTH”> <uses permission android:name=“android.permission.BLUETOOTH_ADMIN”> </manifest>
Setting up the Bluetooth Adapter • Use BluetoothAdapter to get a reference to the Bluetooth device • If Bluetooth device is not supported the adapter returns a NULL • Enable Bluetooth device using an Intent and starting a new Activity with the Bluetooth device • It does ask the user whether he wants to enable the device • How do you know that the Bluetooth device is enabled? --- the resultcode in onActivityResult() callback will be RESULT_OK. Bluetooth adapter = BluetoothAdapter.getDefaultAdapter(); if(adapter == null) { //Device does not support Bluetooth. } if(!adapter.isEnabled()) { Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBT, REQUEST_ENABLE_BT); }
Discovering devices • First step is to find devices that you have already paired with: these are devices you do not need to pair to get connected • Use a broadcast receiver discover new Bluetooth devices Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices(); if (pairedDevices.size() > 0) { for(BluetoothDevice device: pairedDevices) { //get access to the devices name through device.getName(); //get access to the devices MAC address through device.getAddress(); } } //discovering devices adapter.startDiscover(); private final BroadcastReceivermReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //get the name of the device through device.getName(); //get the MAC address of the device through device.getAddress(); } } IntentFilter filter = new IntentFilter(Bluetooth.ACTION_FOUND); registerReceiver(mReceiver, filte); //register for broadcast receiver when a BT device is found.
Enabling Discovery • Why do you need to set a device’s Bluetooth to Discoverable • If you are a server and you want client devices to connect to you • If you want other devices to see you in order to pair with you • You set it up using an Intent • A parameter that you can set up is the time that you want the device to be discoverable • Default = 120 seconds, 0 forever, max = 3600, < 0 or > 3600 – default is taken. Intent discoverable = new Intent(BluetoothAdapter.BLUETOOTH_ACTION_DISCOVERABLE); Discoverable.putExtras(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverable);
Connecting to a device (server-side) • Just like a TCP socket called BluetoothServerSocket • You wait on an accept() (blocking call) till you receive an incoming connection request • accept() is blocking so it should happen in a separate thread from the UI thread Name of the service Unique ID for the service public class AcceptConnection extends Thread{ private final BluetoothServerSocket soc; public AcceptConnection() { try { soc = adapter.listenUsingRfcommWithServiceRecord(NAME, UDID); } catch(IOExceptione){} } public void run() { BluetoothSocket socket = null; while(true) { try { soc.accept(); } catch(IOExceptione) { break; } if(soc != null) { //spawn another thread to manage the connection } } } }
Connecting to a device (client-end) • Connect() is a blocking call so needs to happen in a thread separate from the UI thread • From the remote device, create a Rfcomm channel for data transfer. public class ClientThread extends Thread { BluetoothSocket temp = null; public ClientThread(Bluetooth device) { try { temp = device.createRfcommSocketToServiceRecord(UDID); }catch(Exceptione) { } } public void run() { adapter.cancelDiscover(); try { temp.connect(); } catch(Exceptione) { } //manage the connection } }
Data transfer using the server/client socket • Attach an InputStream and an OutputStream to the the socket • Use read(byte[]) and write(byte[]) to read and write --- both are blocking calls public class ClientThread extends Thread { BluetoothSocket temp = null; public ClientThread(Bluetooth device) { try { temp = device.createRfcommSocketToServiceRecord(UDID); }catch(Exceptione) { } } public void run() { byte[] buffer = new byte[1024]; intnumbytes; adapter.cancelDiscover(); try { numbytes = temp.read(buffer); //do whatever you want with the bytes } catch(Exceptione) { } //manage the connection } }