如何在多个活动中保持蓝牙连接存在?

时间:2014-01-21 00:42:46

标签: java android multithreading android-activity bluetooth

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

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

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

我是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");
            }
        }
    }

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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