【问题标题】:How to keep a Bluetooth connection alive across multiple activities?如何在多个活动中保持蓝牙连接处于活动状态?
【发布时间】:2014-01-21 00:42:45
【问题描述】:

我在任何地方都找不到具体问题的答案。

我需要一种方法让我的应用程序活动能够通过蓝牙连接单独交换数据。这是我想要做的:

我有一个主要活动,上面有一堆按钮,每个按钮都启动一个新活动。其中一个按钮应该建立蓝牙连接。创建完成后,我希望能够返回到主活动,然后点击不同的按钮打开一个新活动,该活动仍然可以在之前创建的蓝牙连接上发送和接收数据。

我是 java/android 的新手,但我迫切需要帮助,因为我需要为我参与的团队项目设置这个应用程序。目前,我刚刚从互联网上收集了一些代码来创建一个应用程序,该应用程序在启动时简单地连接到特定的 BT 模块。但是,如果我无法打开新页面(活动),这个应用程序就毫无价值了。

connectBluetooth 和 sendReceiveBytes 的类都作为线程启动。但我相信这些线程在它们开始的活动消亡(主要活动)时就会消亡。所以如果有办法做到这一点,请赐教。或者,如果您需要更多信息,请告诉我,我可以为您提供帮助。谢谢大家!

这是我的代码:它只是一个简单的启动活动,可立即连接到名为“RNBT-504D”的 bt 设备。当我离开应用程序并且活动终止时,由于我的 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");
            }
        }
    }

【问题讨论】:

    标签: java android multithreading android-activity bluetooth


    【解决方案1】:

    基本上,您可能需要在主要活动中将您的BluetoothDevice discoveredDevice 声明为一个字段。当实例化其他活动时,将其作为参数传递。

    【讨论】:

      【解决方案2】:

      一种可能不是最佳解决方案的方法是在本机层创建一个守护程序来处理 BT 连接。由于原生代码不受 Android 生命周期管理的限制,它会持续一段时间。因此,您不必担心在活动变为非活动状态时会取消连接。

      【讨论】:

        猜你喜欢
        • 2013-01-27
        • 1970-01-01
        • 2013-07-08
        • 1970-01-01
        • 1970-01-01
        • 2012-01-03
        • 2021-09-13
        • 2013-08-27
        • 2019-09-01
        相关资源
        最近更新 更多