Как сохранить связь Bluetooth в нескольких видах деятельности?
Я не могу найти ответ на мою конкретную проблему нигде.
Мне нужен способ, чтобы все мои приложения могли обмениваться данными через Bluetooth-соединение отдельно. Вот что я пытаюсь сделать:
У меня есть основной вид деятельности с кучей кнопок на нем, каждый из которых начинает новый вид деятельности. Одна из кнопок предназначена для установления соединения Bluetooth. После его создания я хочу иметь возможность вернуться к основному действию, а затем нажать другую кнопку, чтобы открыть новое действие, которое все еще может отправлять и получать данные по соединению Bluetooth, созданному ранее.
Я довольно новичок в Java/ Android, но я остро нуждаюсь в помощи, потому что мне нужно настроить это приложение для командного проекта, частью которого я являюсь. В настоящее время я собираю куски кода со всего Интернета, чтобы создать приложение, которое просто подключается к определенному модулю BT при запуске. Но это приложение бесполезно, если я не могу открыть новые страницы (действия).
Оба класса для connectBluetooth и sendReceiveBytes запускаются как потоки. Но я верю, что эти нити умирают, когда умирает активность, с которой они начинались (основная деятельность). Так что, если есть что сделать, пожалуйста, просветите меня. Или, если вам нужна дополнительная информация, пожалуйста, дайте мне знать, и я могу вам помочь. Спасибо всем!
Вот мой код: это просто один запуск, который сразу подключается к устройству bt с именем "RNBT-504D". И когда я покидаю приложение и активность умирает, соединение закрывается из-за моего метода onDestroy.
Я показал свой широковещательный приемник, который запускает поток подключения и, в случае успеха, запускает поток управления соединением (sendReceiveBytes). Все три класса показаны ниже.
/* This BroadcastReceiver will display discovered Bluetooth devices */
public class myOwnBroadcastReceiver extends BroadcastReceiver {
ConnectToBluetooth connectBT;
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
//Notification that BluetoothDevice is FOUND
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//Gather information about discovered bluetooth device
BluetoothDevice discoveredDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Display more information about the discovered device
if(discoveredDevice.getName().equals("RNBT-504D")){
ToastMaster("Device: " + discoveredDevice.getName() +"\n"+ discoveredDevice.getAddress());
}
//Connect to the discovered Bluetooth device (SeeedBTSlave)
if (discoveredDevice.getName().equals("RNBT-504D")) {
ToastMaster("Connecting you Now !!");
unregisterReceiver(myDiscoverer);
connectBT = new ConnectToBluetooth(discoveredDevice);
//Connect to the the device in a new thread
new Thread(connectBT).start();
}
}
//Notification if bluetooth device is connected
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
ToastMaster("CONNECTED _ YAY");
while (scSocket==null) {
//do nothing
}
if (scSocket!=null) {
sendReceiveBT = new SendReceiveBytes(scSocket);
new Thread(sendReceiveBT).start();
//String red = "r";
//byte[] myByte = stringToBytesUTFCustom(red);
byte[] pronto = new byte[]{0x00, 0x00, 0x00, 0x6E, 0x00, 0x22, 0x00, 0x02, 0x01, 0x56, 0x00, (byte) 0xAC, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x00, 0x15, 0x00, 0x15, 0x00, 0x41, 0x00, 0x15, 0x05, (byte) 0x8C, 0x01, 0x56, 0x00, 0x56, 0x00, 0x15, 0x0E, 0x44};
sendReceiveBT.write(pronto);
}
}
if(BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)){
BluetoothDevice discoveredDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
ToastMaster("Disconnected from "+discoveredDevice.getName());
}
}
}
public static byte[] stringToBytesUTFCustom(String str) {
char[] buffer = str.toCharArray();
byte[] b = new byte[buffer.length << 1];
for (int i = 0; i < buffer.length; i++) {
int bpos = i << 1;
b[bpos] = (byte) ((buffer[i]&0xFF00)>>8);
b[bpos + 1] = (byte) (buffer[i]&0x00FF);
}
return b;
}
public class ConnectToBluetooth implements Runnable {
private BluetoothDevice btShield;
private BluetoothSocket mySocket = null;
private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public ConnectToBluetooth(BluetoothDevice bluetoothShield) {
btShield = bluetoothShield;
try {
mySocket = btShield.createRfcommSocketToServiceRecord(uuid);
}
catch(IOException createSocketException) {
//Problem with creating a socket
Log.e("ConnectToBluetooth", "Error with Socket");
}
}
@Override
public void run() {
/* Cancel discovery on Bluetooth Adapter to prevent slow connection */
bluetooth.cancelDiscovery();
try {
/*Connect to the bluetoothShield through the Socket. This will block
until it succeeds or throws an IOException */
mySocket.connect();
scSocket=mySocket;
}
catch (IOException connectException) {
Log.e("ConnectToBluetooth", "Error with Socket Connection");
try {
mySocket.close(); //try to close the socket
}
catch(IOException closeException) {
}
return;
}
}
/* Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mySocket.close();
}
catch (IOException e) {
}
}
}
private class SendReceiveBytes implements Runnable {
private BluetoothSocket btSocket;
private InputStream btInputStream = null;
private OutputStream btOutputStream = null;
String TAG = "SendReceiveBytes";
public SendReceiveBytes(BluetoothSocket socket) {
btSocket = socket;
try {
btInputStream = btSocket.getInputStream();
btOutputStream = btSocket.getOutputStream();
}
catch (IOException streamError) {
Log.e(TAG, "Error when getting input or output Stream");
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = btInputStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
}
catch (IOException e) {
Log.e(TAG, "Error reading from btInputStream");
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
btOutputStream.write(bytes);
}
catch (IOException e) {
Log.e(TAG, "Error when writing to btOutputStream");
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
btSocket.close();
}
catch (IOException e) {
Log.e(TAG, "Error when closing the btSocket");
}
}
}
2 ответа
Один из подходов, который может быть не самым лучшим решением, - это создание демона на собственном уровне для обработки соединения BT. Поскольку нативный код не ограничен управлением жизненным циклом Android, он будет длиться с течением времени. Таким образом, вам не нужно беспокоиться, что соединение будет отменено, когда активность станет неактивной.
В основном вы должны объявить BluetoothDevice discoveredDevice
как поле, вероятно, в вашей основной деятельности. При создании других действий передайте это как параметр.