Welcome, Guest: Register On Nairaland / LOGIN! / Trending / Recent / NewStats: 3,195,081 members, 7,957,031 topics. Date: Tuesday, 24 September 2024 at 05:19 AM |
Nairaland Forum / Science/Technology / Programming / Bluetooth Connectivity Between Android And Arduino (822 Views)
Which One Should I Focus Between Android App Development And Web Application On / Udacity/google Africa Challenge Scholarship For Android And Web Development! / Free Arduino Tutorial (2) (3) (4)
(1) (Reply)
Bluetooth Connectivity Between Android And Arduino by KodeHauz: 3:19pm On Apr 15, 2019 |
Recently, I developed an android application that transfers data to and from an Arduino through Bluetooth. This post aims to highlight how this Bluetooth connection data transfer between the two devices is achieved. Disclaimer: The scope of this article is limited to the Android application. All Arduino hardware configurations are excluded. This workflow will be discussed in three stages: - Device Discovery; - Connection and - Data transfer Discovery First things first, the necessary permissions must be declared in the manifest file: <manifest ... > <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> ... </manifest> On the Bluetooth devices discovery Activity, a BroadcastReceiver listens for discovered devices and updates a Recyclerview showing a list of available devices (paired and unpaired). The receiver is detailed thus: @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // If it's already paired, skip it, because it's been listed already if (device.getBondState() != BluetoothDevice.BOND_BONDED) { // only add device to the list if it is not already there if (!mBtDevices.contains(device)) mBtDevices.add(device); // update the reccyclerview here } // When discovery is finished, } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { setProgressBarIndeterminateVisibility(false); } } Registration for this broadcast is done in the activity’s onResume() method: // Register for broadcasts when a device is discovered IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); this.registerReceiver(mReceiver, filter); // Register for broadcasts when discovery has finished IntentFilter finishedFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); this.registerReceiver(mReceiver, finishedFilter); And unregistered in onPause() method this.unregisterReceiver(mReceiver); Connection Bluetooth connectivity with any selected visible device is established through a service that is initialized at application launch and closed when the application is terminated as shown: @Override public void onCreate() { super.onCreate(); // initialize mBluetoothCommService = new BluetoothCommunicationService(); } @Override public void onTerminate() { super.onTerminate(); if (mBluetoothCommService != null) { mBluetoothCommService.stop(); } } This service queries the local Bluetooth adapter for paired Bluetooth devices and establishes a connection by spinning up a thread. RFCOMM channel/socket creation and connection are performed on this thread as shown: private class ConnectThread extends Thread { private final BluetoothSocket mSocket; private final BluetoothDevice mDevice; public ConnectThread(BluetoothDevice device) { mDevice = device; BluetoothSocket tmp = null; // Get a BluetoothSocket for a connection with the given BluetoothDevice try { tmp = device.createRfcommSocketToServiceRecord(MY_UUID); } catch (IOException e) { Log.e(TAG, "Socket Type: create() failed", e); } mSocket = tmp; mState = STATE_CONNECTING; } public void run() { // Always cancel discovery because it will slow down a connection mAdapter.cancelDiscovery(); // Make a connection to the BluetoothSocket try { // its a blocking call and will only return on a successful connection or an exception mSocket.connect(); } catch (IOException e) { try { mSocket.close(); // Close the socket } catch (IOException e2) { Log.e(TAG, "unable to close() socket during connection failure", e2); } // Send a failure message back to the Activity Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(Constants.TOAST, "Unable to connect device" msg.setData(bundle); mHandler.sendMessage(msg); mState = STATE_NONE; return; } // Reset the ConnectThread because we're done synchronized (BluetoothCommunicationService.this) { mConnectThread = null; } // Cancel the thread that completed the connection if (mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; } // Cancel any thread currently running a connection if (mConnectedThread != null) { mConnectedThread.cancel(); mConnectedThread = null; } // Start the thread to manage the connection and perform transmissions mConnectedThread = new ConnectedThread(socket); mConnectedThread.start(); // Send the name of the connected device back to the UI Activity Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME); Bundle bundle = new Bundle(); bundle.putString(Constants.DEVICE_NAME, device.getName()); msg.setData(bundle); mHandler.sendMessage(msg); } public void cancel() { try { mSocket.close(); } catch (IOException e) { Log.e(TAG, "close() of connect socket failed", e); } } } Data Transfer With connection established, data can be transmitted through a new thread that handles the InputStreams and OutputStreams: private class ConnectedThread extends Thread { private final BluetoothSocket mSocket; private final InputStream mInStream; private final OutputStream mOutStream; private ConnectedThread(BluetoothSocket socket) { Log.d(TAG, "create ConnectedThread: " + socket); mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the BluetoothSocket input and output streams try { tmpIn = socket.getInputStream(); } catch (IOException e) { Log.e(TAG, "Error occurred when creating input stream", e); } try { tmpOut = socket.getOutputStream(); } catch (IOException e) { Log.e(TAG, "Error occurred when creating output stream", e); } mInStream = tmpIn; mOutStream = tmpOut; mState = STATE_CONNECTED; } public void run() { byte[] buffer = new byte[1024]; int bytes; // Keep listening to the InputStream while connected while (mState == STATE_CONNECTED) { try { // Read from the InputStream bytes = mInStream.read(buffer); // Send the obtained bytes to the UI Activity mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer).sendToTarget(); } catch (IOException e) { // Send a failure message back to the Activity Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString(Constants.TOAST, "Device connection was lost" msg.setData(bundle); mHandler.sendMessage(msg); mState = STATE_NONE; break; } } } // Write to the connected OutStream. private void write(byte[] buffer) { try { mOutStream.write(buffer); // Share the sent message back to the UI Activity mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); } catch (IOException e) { Log.e(TAG, "Exception during write", e); } } private void cancel() { try { mSocket.close(); } catch (IOException e) { Log.e(TAG, "close() of connect socket failed", e); } } } Because this service runs in the background, communication to / from the main UI thread is established by creating a handler which updates the UI (toasts, dialogs, view updated) based on the messsage received. Each activity that requires communication with the service creates an instance of the handler and performs necessary action by overriding the handleMessage() method: public class BluetoothCommunicationHandler extends Handler { private WeakReference<Activity> mActivity; public BluetoothCommunicationHandler() { mActivity = null; } public void setCurrentActivity(Activity activity) { mActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { Activity activity = mActivity.get(); if (activity != null) { switch (msg.what) { case Constants.MESSAGE_WRITE: byte[] writeBuf = (byte[]) msg.obj; // construct a string from the buffer String writeMessage = new String(writeBuf); break; case Constants.MESSAGE_READ: byte[] readBuf = (byte[]) msg.obj; // construct a string from the valid bytes in the buffer String readMessage = new String(readBuf, 0, msg.arg1); // do something with the received message break; case Constants.MESSAGE_DEVICE_NAME: // save the connected device's name String deviceName = msg.getData().getString(Constants.DEVICE_NAME); break; } } } } https://kodehauz.com/blog/data-transfer-between-android-and-arduino-over-bluetooth 1 Like |
(1) (Reply)
I Build Websites And Mobile Apps / How To Browse Any Website With Freebasics Data 2019 / I Need Someone That Has Worked With OSSN - Open Source Social Network Framework
(Go Up)
Sections: politics (1) business autos (1) jobs (1) career education (1) romance computers phones travel sports fashion health religion celebs tv-movies music-radio literature webmasters programming techmarket Links: (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) Nairaland - Copyright © 2005 - 2024 Oluwaseun Osewa. All rights reserved. See How To Advertise. 20 |