简体   繁体   English

如何在多个活动之间保持蓝牙连接有效?

[英]How to keep a Bluetooth connection alive across multiple activities?

I cannot find an answer to my specific problem anywhere. 我在任何地方都找不到我的特定问题的答案。

I need a way to have my application activities be able to all separately exchang data with a Bluetooth connection. 我需要一种使我的应用程序活动能够通过蓝牙连接分别交换数据的方法。 Here's what I am trying to do: 这是我想做的事情:

I have a main activity with a bunch of buttons on it that each start a new activity. 我有一个主要活动,上面有一堆按钮,每个按钮都启动一个新活动。 One of the buttons is supposed to establish the Bluetooth connection. 其中一个按钮应该建立蓝牙连接。 After it is created, I want to be able to return to the main activity and then hit a different button to open a new activity that can still send and receive data on the Bluetooth connection created earlier. 创建完成后,我希望能够返回到主活动,然后单击另一个按钮以打开一个新活动,该活动仍可以通过先前创建的蓝牙连接发送和接收数据。

I'm pretty new at java/android but I'm in desperate need for help because I need to set this app up for a team project I am a part of. 我在java / android上还很新,但是我迫切需要帮助,因为我需要为参与其中的团队项目设置此应用。 Currently I've just been gathering bits of code from around the internet to create an app that simply connects to a specific BT module upon start-up. 目前,我只是从互联网上收集一些代码来创建一个应用程序,该应用程序在启动时仅连接到特定的BT模块。 But this app is kind of worthless if I can't open new pages (activities). 但是,如果我无法打开新页面(活动),则该应用毫无价值。

Both the classes for the connectBluetooth and sendReceiveBytes are started as threads. connectBluetooth和sendReceiveBytes的两个类都作为线程启动。 But I believe those threads die when the activity they were started in dies (main activity). 但是我相信这些线程在活动开始时(主要活动)死亡时就会死亡。 So if there is anyway to do this, please enlighten me. 因此,如果有任何必要,请赐教。 Or if you need more information, please let me know and I can help you out. 或者,如果您需要更多信息,请告诉我,我们会为您提供帮助。 Thanks all! 谢谢大家!

Here is my code: It is simply a single startup activity that immediately connects to a bt device named "RNBT-504D". 这是我的代码:这只是一个单独的启动活动,它立即连接到名为“ RNBT-504D”的bt设备。 And when I leave the application and the activity dies, the connection is closed because of my onDestroy method. 当我离开应用程序并且活动终止时,由于我的onDestroy方法,该连接已关闭。

I have shown my broadcast receiver which starts the connect thread and if successful, starts a manage conection thread (sendReceiveBytes). 我已经展示了广播接收器,该接收器将启动连接线程,如果成功,则将启动管理连接线程(sendReceiveBytes)。 All three classes are shown below. 这三个类别均显示如下。

/* 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");
            }
        }
    }

Basically you need to declare your BluetoothDevice discoveredDevice as a field probably in your main activity. 基本上,您需要在您的主要活动中将BluetoothDevice discoveredDevice声明为一个字段。 When instantiating other activities pass this as a parameter. 实例化其他活动时,将此作为参数传递。

One approach, which may not be the best solution, is to create a daemon at native layer to handle the BT connection. 一种可能不是最佳解决方案的方法是在本机层创建一个守护程序来处理BT连接。 Since native code is not limited by Android's life-cycle management, it will last over the time. 由于本机代码不受Android生命周期管理的限制,因此它会持续一段时间。 So you do not need to worry that the connection be canceled when the activity becomes inactive. 因此,您不必担心活动变为非活动状态时会取消连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM