How to keep Bluetooth connection background?
13,842
Yes, I found a working solution for running Bluetooth background in Android. Below is the code I have used in my android app.
public class BluetoothServices extends Service {
private BluetoothAdapter mBluetoothAdapter;
public static final String B_DEVICE = "MY DEVICE";
public static final String B_UUID = "00001101-0000-1000-8000-00805f9b34fb";
// 00000000-0000-1000-8000-00805f9b34fb
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
private ConnectBtThread mConnectThread;
private static ConnectedBtThread mConnectedThread;
private static Handler mHandler = null;
public static int mState = STATE_NONE;
public static String deviceName;
public static BluetoothDevice sDevice = null;
public Vector<Byte> packData = new Vector<>(2048);
//IBinder mIBinder = new LocalBinder();
@Nullable
@Override
public IBinder onBind(Intent intent) {
//mHandler = getApplication().getHandler();
return mBinder;
}
public void toast(String mess){
Toast.makeText(this,mess,Toast.LENGTH_SHORT).show();
}
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
BluetoothServices getService() {
// Return this instance of LocalService so clients can call public methods
return BluetoothServices.this;
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String deviceg = intent.getStringExtra("bluetooth_device");
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
connectToDevice(deviceg);
return START_STICKY;
}
private synchronized void connectToDevice(String macAddress){
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
if (mState == STATE_CONNECTING){
if (mConnectThread != null){
mConnectThread.cancel();
mConnectThread = null;
}
}
if (mConnectedThread != null){
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectBtThread(device);
toast("connecting");
mConnectThread.start();
setState(STATE_CONNECTING);
}
private void setState(int state){
mState = state;
if (mHandler != null){
// mHandler.obtainMessage();
}
}
public synchronized void stop(){
setState(STATE_NONE);
if (mConnectThread != null){
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null){
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mBluetoothAdapter != null){
mBluetoothAdapter.cancelDiscovery();
}
stopSelf();
}
public void sendData(String message){
if (mConnectedThread!= null){
mConnectedThread.write(message.getBytes());
toast("sent data");
}else {
Toast.makeText(BluetoothServices.this,"Failed to send data",Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean stopService(Intent name) {
setState(STATE_NONE);
if (mConnectThread != null){
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null){
mConnectedThread.cancel();
mConnectedThread = null;
}
mBluetoothAdapter.cancelDiscovery();
return super.stopService(name);
}
/*private synchronized void connected(BluetoothSocket mmSocket){
if (mConnectThread != null){
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null){
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectedThread = new ConnectedBtThread(mmSocket);
mConnectedThread.start();
setState(STATE_CONNECTED);
}*/
private class ConnectBtThread extends Thread{
private final BluetoothSocket mSocket;
private final BluetoothDevice mDevice;
public ConnectBtThread(BluetoothDevice device){
mDevice = device;
BluetoothSocket socket = null;
try {
socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(B_UUID));
} catch (IOException e) {
e.printStackTrace();
}
mSocket = socket;
}
@Override
public void run() {
mBluetoothAdapter.cancelDiscovery();
try {
mSocket.connect();
Log.d("service","connect thread run method (connected)");
SharedPreferences pre = getSharedPreferences("BT_NAME",0);
pre.edit().putString("bluetooth_connected",mDevice.getName()).apply();
} catch (IOException e) {
try {
mSocket.close();
Log.d("service","connect thread run method ( close function)");
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
//connected(mSocket);
mConnectedThread = new ConnectedBtThread(mSocket);
mConnectedThread.start();
}
public void cancel(){
try {
mSocket.close();
Log.d("service","connect thread cancel method");
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectedBtThread extends Thread{
private final BluetoothSocket cSocket;
private final InputStream inS;
private final OutputStream outS;
private byte[] buffer;
public ConnectedBtThread(BluetoothSocket socket){
cSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
inS = tmpIn;
outS = tmpOut;
}
@Override
public void run() {
buffer = new byte[1024];
int mByte;
try {
mByte= inS.read(buffer);
} catch (IOException e) {
e.printStackTrace();
}
Log.d("service","connected thread run method");
}
public void write(byte[] buff){
try {
outS.write(buff);
} catch (IOException e) {
e.printStackTrace();
}
}
private void cancel(){
try {
cSocket.close();
Log.d("service","connected thread cancel method");
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onDestroy() {
this.stop();
super.onDestroy();
}
}
Related videos on Youtube
![Bhanu Prakash Pasupula](https://i.stack.imgur.com/EayAe.jpg?s=256&g=1)
Author by
Bhanu Prakash Pasupula
Failure by choise, an entrepreneur by passion.
Updated on June 04, 2022Comments
-
Bhanu Prakash Pasupula about 2 years
I have created a Bluetooth Activity class in the android app, which works fine for all the Bluetooth functionalities like: scanning, pairing, connecting, sending and receiving data.
The real problem is when the Activity is destroyed. Bluetooth is disconnecting.
how can I make Bluetooth connection throughout the app. and I want to send data to the Bluetooth from other activities.
Help me to implement this in an easy way?
public class BTActivity extends AppCompatActivity { ArrayList<BluetoothDevice> devices = new ArrayList<>(); BluetoothAdapter mBluetoothAdapter; BluetoothDevice mBluetoothDevice; ArrayAdapter<BluetoothDevice> arrayAdapter; ConnectThread c; private static final String TAG = "MY_BT"; ListView lvPaired; Button BluetoothOnOff, ScanBt, pairedlist, sendButton, btDisconnect, incrementBtn, decrementBtn; EditText input_text; TextView ConnectedTo; FragmentManager fm = getSupportFragmentManager(); UUID BHANU_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bt); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); lvPaired = findViewById(R.id.btPairedLV); pairedlist = findViewById(R.id.btPaired); input_text = findViewById(R.id.user_input); sendButton = findViewById(R.id.btnSend); BluetoothOnOff = findViewById(R.id.offOn_bt); ScanBt = findViewById(R.id.scan_bt); ConnectedTo = findViewById(R.id.current_connected_bluetooth); btDisconnect = findViewById(R.id.bt_disconnect); incrementBtn = findViewById(R.id.incrementBtn); decrementBtn = findViewById(R.id.decrementBtn); onClickListener(); pairedList(); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); registerReceiver(mReceiver, filter); } public void onClickListener(){ pairedlist.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (arrayAdapter != null){ arrayAdapter.clear(); } pairedList(); } }); lvPaired.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { BluetoothDevice device = (BluetoothDevice) parent.getItemAtPosition(position); c = new ConnectThread(device, true); c.start(); } }); sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String text = input_text.getText().toString(); c.sendData(text); input_text.setText(""); } }); BluetoothOnOff.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!mBluetoothAdapter.isEnabled()){ mBluetoothAdapter.enable(); BluetoothOnOff.setText("ON"); }else { mBluetoothAdapter.disable(); BluetoothOnOff.setText("OFF"); } } }); ScanBt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ScanFragment scanFragment = new ScanFragment(); scanFragment.show(fm,"ScanBT"); //ScanFragment scanFragment = new ScanFragment(); //scanFragment.show(fm,"Scan Fragment"); } }); btDisconnect.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { c.cancel(); } }); incrementBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { c.sendData("a"); } }); decrementBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { c.sendData("b"); } }); } public void toast(String message) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { unregisterReceiver(mReceiver); super.onDestroy(); } public void pairedList() { //arrayAdapter.clear(); devices.addAll(mBluetoothAdapter.getBondedDevices()); arrayAdapter = new ArrayAdapter<BluetoothDevice>(this, android.R.layout.simple_list_item_1,android.R.id.text1, devices); lvPaired.setAdapter(arrayAdapter); arrayAdapter.notifyDataSetChanged(); } BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { toast("connected"); BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); ConnectedTo.setText(device.getName()); btDisconnect.setVisibility(View.VISIBLE); //getActionBar().setSubtitle(device.getName()); Log.d("BT", "connected to"); } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { toast("disconnected"); ConnectedTo.setText("None"); btDisconnect.setVisibility(View.INVISIBLE); // getActionBar().setSubtitle(""); Log.d("BT", "disconnected"); } } }; public class ConnectThread extends Thread { BluetoothDevice cDevice; BluetoothSocket socket; ConnectedThread ct; ConnectThread(BluetoothDevice device, boolean insecureConnection) { cDevice = device; try { if (insecureConnection) { socket = device.createInsecureRfcommSocketToServiceRecord(BHANU_UUID); } else { socket = device.createRfcommSocketToServiceRecord(BHANU_UUID); } } catch (IOException e) { e.getMessage(); } } public void run() { mBluetoothAdapter.cancelDiscovery(); try { Log.d("BT", "Socket ready to connect"); socket.connect(); Log.d("BT", "Socket connected"); // out = socket.getOutputStream(); // input = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (final IOException e) { e.getMessage(); } ct = new ConnectedThread(socket); //ct.write("Q-smart".getBytes()); /*try { socket.close(); } catch (final IOException closeException) { closeException.getMessage(); }*/ } private void sendData(String message){ Log.d(TAG,message); if (socket != null){ ct.write(message.getBytes()); }else { toast("Please connect to bluetooth first"); } } public void cancel() { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; private byte[] mmBuffer; // mmBuffer store for the stream public ConnectedThread(BluetoothSocket socket) { mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the input and output streams; using temp objects because // member streams are final. 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); } mmInStream = tmpIn; mmOutStream = tmpOut; } public void run() { mmBuffer = new byte[1024]; int numBytes; // bytes returned from read() // Keep listening to the InputStream until an exception occurs. while (true) { try { // Read from the InputStream. numBytes = mmInStream.read(mmBuffer); // Send the obtained bytes to the UI activity. /* Message readMsg = mHandler.obtainMessage( MessageConstants.MESSAGE_READ, numBytes, -1, mmBuffer); readMsg.sendToTarget();*/ } catch (IOException e) { Log.d(TAG, "Input stream was disconnected", e); break; } } } // Call this from the main activity to send data to the remote device. public void write(byte[] bytes) { try { mmOutStream.write(bytes); // Share the sent message with the UI activity. /* Message writtenMsg = mHandler.obtainMessage( MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer); writtenMsg.sendToTarget();*/ } catch (IOException e) { Log.e(TAG, "Error occurred when sending data", e); // Send a failure message back to the activity. /* Message writeErrorMsg = mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST); Bundle bundle = new Bundle(); bundle.putString("toast", "Couldn't send data to the other device"); writeErrorMsg.setData(bundle); mHandler.sendMessage(writeErrorMsg);*/ } } } }