蓝牙

作者: 守感不好 | 来源:发表于2020-11-03 21:05 被阅读0次

    1.添加蓝牙的使用权限

    //管理蓝牙的权限

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    //使用蓝牙的权限

    <uses-permission android:name="android.permission.BLUETOOTH" />

    2.蓝牙的搜索、配对;这些很容易操作,在这里不做过多的介绍;这里我们直接获取已配对的蓝牙设备(注:已配对的不一定能成功建立连接)通过BlueToothAdapter来获得已配对文件

    mBtAdapter = BluetoothAdapter.getDefaultAdapter();

    Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();

    获取到pairedDevices后利用adapter将已配对列表显示出来

    3.点击某条已配对设备,试图建立连接,并得知是否能连接上

    点击item后首先取消所有的蓝牙检测

    试图建立连接

    mBtAdapter.cancelDiscovery();

    connectDevice(data, true);

    4.封装了一个蓝牙类;完成蓝牙的连接交互BluetoothChatService

    public class BluetoothChatService {

        // Debugging

        private  String TAG = "BluetoothChatService";

        // Name for the SDP record when creating server socket

        private  String NAME_SECURE = "BluetoothChatSecure";

        private static final String NAME_INSECURE = "BluetoothChatInsecure";

        // Unique UUID for this application

        private  UUID MY_UUID_SECURE =

                UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

    //    private  UUID MY_UUID_SECURE =UUID.randomUUID();

    //    private  UUID MY_UUID_INSECURE =UUID.randomUUID();

        private  UUID MY_UUID_INSECURE =

                UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");

        // Member fields

        private  BluetoothAdapter mAdapter;

        private  Handler mHandler;

        private AcceptThread mSecureAcceptThread;

        private AcceptThread mInsecureAcceptThread;

        private ConnectThread mConnectThread;

        private ConnectedThread mConnectedThread;

        private int mState;

        private int mNewState;

        // Constants that indicate the current connection state

        public static final int STATE_NONE = 0;      // we're doing nothing

        public static final int STATE_LISTEN = 1;    // now listening for incoming connections

        public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection

        public static final int STATE_CONNECTED = 3;  // now connected to a remote device

        /**

        * Constructor. Prepares a new BluetoothChat session.

        *

        * @param context The UI Activity Context

        * @param handler A Handler to send messages back to the UI Activity

        */

        public BluetoothChatService(Context context, Handler handler) {

            mAdapter = BluetoothAdapter.getDefaultAdapter();

            mState = STATE_NONE;

            mNewState = mState;

            mHandler = handler;

        }

        /**

        * Update UI title according to the current state of the chat connection

        */

        private synchronized void updateUserInterfaceTitle() {

            mState = getState();

            Log.d(TAG, "updateUserInterfaceTitle() " + mNewState + " -> " + mState);

            mNewState = mState;

            // Give the new state to the Handler so the UI Activity can update

            mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, mNewState, -1).sendToTarget();

        }

        /**

        * Return the current connection state.

        */

        public synchronized int getState() {

            return mState;

        }

        /**

        * Start the chat service. Specifically start AcceptThread to begin a

        * session in listening (server) mode. Called by the Activity onResume()

        */

        public synchronized void start() {

            Log.d(TAG, "start");

            // Cancel any thread attempting to make a connection

            if (mConnectThread != null) {

                mConnectThread.cancel();

                mConnectThread = null;

            }

            // Cancel any thread currently running a connection

            if (mConnectedThread != null) {

                mConnectedThread.cancel();

                mConnectedThread = null;

            }

            // Start the thread to listen on a BluetoothServerSocket

            if (mSecureAcceptThread == null) {

                mSecureAcceptThread = new AcceptThread(true);

                mSecureAcceptThread.start();

            }

            if (mInsecureAcceptThread == null) {

                mInsecureAcceptThread = new AcceptThread(false);

                mInsecureAcceptThread.start();

            }

            // Update UI title

            updateUserInterfaceTitle();

        }

        /**

        * Start the ConnectThread to initiate a connection to a remote device.

        *

        * @param device The BluetoothDevice to connect

        * @param secure Socket Security type - Secure (true) , Insecure (false)

        */

        public synchronized void connect(BluetoothDevice device, boolean secure) {

            Log.d(TAG, "connect to: " + device);

            // Cancel any thread attempting to make a connection

            if (mState == STATE_CONNECTING) {

                if (mConnectThread != null) {

                    mConnectThread.cancel();

                    mConnectThread = null;

                }

            }

            // Cancel any thread currently running a connection

            if (mConnectedThread != null) {

                mConnectedThread.cancel();

                mConnectedThread = null;

            }

            // Start the thread to connect with the given device

            mConnectThread = new ConnectThread(device, secure);

            mConnectThread.start();

            // Update UI title

            updateUserInterfaceTitle();

        }

        /**

        * Start the ConnectedThread to begin managing a Bluetooth connection

        *

        * @param socket The BluetoothSocket on which the connection was made

        * @param device The BluetoothDevice that has been connected

        */

        public synchronized void connected(BluetoothSocket socket, BluetoothDevice

                device, final String socketType) {

            Log.d(TAG, "connected, Socket Type:" + socketType);

            // Cancel the thread that completed the connection

            if (mConnectThread != null) {

                mConnectThread.cancel();

                mConnectThread = null;

            }

            // Cancel any thread currently running a connection

            if (mConnectedThread != null) {

                mConnectedThread.cancel();

                mConnectedThread = null;

            }

            // Cancel the accept thread because we only want to connect to one device

            if (mSecureAcceptThread != null) {

                mSecureAcceptThread.cancel();

                mSecureAcceptThread = null;

            }

            if (mInsecureAcceptThread != null) {

                mInsecureAcceptThread.cancel();

                mInsecureAcceptThread = null;

            }

            // Start the thread to manage the connection and perform transmissions

            mConnectedThread = new ConnectedThread(socket, socketType);

            mConnectedThread.start();

            // Send the name of the connected device back to the UI Activity

            Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);

            Bundle bundle = new Bundle();

            bundle.putString(Constants.DEVICE_NAME, device.getName());

            msg.setData(bundle);

            mHandler.sendMessage(msg);

            // Update UI title

            updateUserInterfaceTitle();

        }

        /**

        * Stop all threads

        */

        public synchronized void stop() {

            Log.d(TAG, "stop");

            if (mConnectThread != null) {

                mConnectThread.cancel();

                mConnectThread = null;

            }

            if (mConnectedThread != null) {

                mConnectedThread.cancel();

                mConnectedThread = null;

            }

            if (mSecureAcceptThread != null) {

    //            mSecureAcceptThread.cancel();

                mSecureAcceptThread.cancel();

                mSecureAcceptThread = null;

            }

            if (mInsecureAcceptThread != null) {

                mInsecureAcceptThread.cancel();

                mInsecureAcceptThread = null;

            }

            mState = STATE_NONE;

            // Update UI title

            updateUserInterfaceTitle();

        }

        /**

        * Write to the ConnectedThread in an unsynchronized manner

        *

        * @param out The bytes to write

        * @see ConnectedThread#write(byte[])

        */

        public void write(byte[] out) {

            // Create temporary object

            ConnectedThread r;

            // Synchronize a copy of the ConnectedThread

            synchronized (this) {

                if (mState != STATE_CONNECTED) return;

                r = mConnectedThread;

            }

            // Perform the write unsynchronized

            r.write(out);

        }

        /**

        * Indicate that the connection attempt failed and notify the UI Activity.

        */

        private void connectionFailed() {

            // Send a failure message back to the Activity

            Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);

            Bundle bundle = new Bundle();

            bundle.putString(Constants.TOAST, "Unable to connect device");

            msg.setData(bundle);

            mHandler.sendMessage(msg);

            mState = STATE_NONE;

            // Update UI title

            updateUserInterfaceTitle();

            // Start the service over to restart listening mode

            BluetoothChatService.this.start();

        }

        /**

        * Indicate that the connection was lost and notify the UI Activity.

        */

        private void connectionLost() {

            // Send a failure message back to the Activity

            Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);

            Bundle bundle = new Bundle();

            bundle.putString(Constants.TOAST, "Device connection was lost");

            msg.setData(bundle);

            mHandler.sendMessage(msg);

            mState = STATE_NONE;

            // Update UI title

            updateUserInterfaceTitle();

            // Start the service over to restart listening mode

            BluetoothChatService.this.start();

        }

        /**

        * This thread runs while listening for incoming connections. It behaves

        * like a server-side client. It runs until a connection is accepted

        * (or until cancelled).

        */

        private class AcceptThread extends Thread {

            // The local server socket

            private final BluetoothServerSocket mmServerSocket;

            private String mSocketType;

            public AcceptThread(boolean secure) {

                BluetoothServerSocket tmp = null;

                mSocketType = secure ? "Secure" : "Insecure";

                // Create a new listening server socket

                try {

                    if (secure) {

                        tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,

                                MY_UUID_SECURE);

                    } else {

                        tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(

                                NAME_INSECURE, MY_UUID_INSECURE);

                    }

                } catch (IOException e) {

                    Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);

                }

                mmServerSocket = tmp;

                mState = STATE_LISTEN;

            }

            public void run() {

                Log.d(TAG, "Socket Type: " + mSocketType +

                        "BEGIN mAcceptThread" + this);

                setName("AcceptThread" + mSocketType);

                BluetoothSocket socket = null;

                // Listen to the server socket if we're not connected

                while (mState != STATE_CONNECTED) {

                    try {

                        // This is a blocking call and will only return on a

                        // successful connection or an exception

                        socket = mmServerSocket.accept();

                    } catch (IOException e) {

                        Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);

                        break;

                    }

                    // If a connection was accepted

                    if (socket != null) {

                        synchronized (BluetoothChatService.this) {

                            switch (mState) {

                                case STATE_LISTEN:

                                case STATE_CONNECTING:

                                    // Situation normal. Start the connected thread.

                                    connected(socket, socket.getRemoteDevice(),

                                            mSocketType);

                                    break;

                                case STATE_NONE:

                                case STATE_CONNECTED:

                                    // Either not ready or already connected. Terminate new socket.

                                    try {

                                        socket.close();

                                    } catch (IOException e) {

                                        Log.e(TAG, "Could not close unwanted socket", e);

                                    }

                                    break;

                            }

                        }

                    }

                }

                Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);

            }

            public void cancel() {

                Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);

                try {

                    mmServerSocket.close();

                } catch (IOException e) {

                    Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);

                }

            }

        }

        /**

        * This thread runs while attempting to make an outgoing connection

        * with a device. It runs straight through; the connection either

        * succeeds or fails.

        */

        private class ConnectThread extends Thread {

            private  BluetoothSocket mmSocket;

            private  BluetoothDevice mmDevice;

            private String mSocketType;

            public ConnectThread(BluetoothDevice device, boolean secure) {

                mmDevice = device;

                BluetoothSocket tmp = null;

                mSocketType = secure ? "Secure" : "Insecure";

                // Get a BluetoothSocket for a connection with the

                // given BluetoothDevice

                try {

                    if (secure) {

                        tmp = device.createRfcommSocketToServiceRecord(

                                MY_UUID_SECURE);

                    } else {

                        tmp = device.createInsecureRfcommSocketToServiceRecord(

                                MY_UUID_INSECURE);

                    }

                } catch (IOException e) {

                    Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);

                }

                mmSocket = tmp;

                mState = STATE_CONNECTING;

            }

            public void run() {

                Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);

                setName("ConnectThread" + mSocketType);

                // Always cancel discovery because it will slow down a connection

                mAdapter.cancelDiscovery();

                // Make a connection to the BluetoothSocket

                try {

                    // This is a blocking call and will only return on a

                    // successful connection or an exception

                    mmSocket.connect();

                } catch (IOException e) {

                    // Close the socket

                    try {

                        mmSocket.close();

    //                    mmSocket = null;

                    } catch (IOException e2) {

                        Log.e(TAG, "unable to close() " + mSocketType +

                                " socket during connection failure", e2);

                    }

                    connectionFailed();

                    return;

                }

                // Reset the ConnectThread because we're done

                synchronized (BluetoothChatService.this) {

                    mConnectThread = null;

                }

                // Start the connected thread

                connected(mmSocket, mmDevice, mSocketType);

            }

            public void cancel() {

                try {

                    if (mmSocket!=null){

                        mmSocket.close();

    //                    mmSocket=null;

                    }

                } catch (IOException e) {

                    Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);

                }

            }

        }

        /**

        * This thread runs during a connection with a remote device.

        * It handles all incoming and outgoing transmissions.

        */

        private class ConnectedThread extends Thread {

            private final BluetoothSocket mmSocket;

            private final InputStream mmInStream;

            private final OutputStream mmOutStream;

            public ConnectedThread(BluetoothSocket socket, String socketType) {

                Log.d(TAG, "create ConnectedThread: " + socketType);

                mmSocket = socket;

                InputStream tmpIn = null;

                OutputStream tmpOut = null;

                // Get the BluetoothSocket input and output streams

                try {

                    tmpIn = socket.getInputStream();

                    tmpOut = socket.getOutputStream();

                } catch (IOException e) {

                    Log.e(TAG, "temp sockets not created", e);

                }

                mmInStream = tmpIn;

                mmOutStream = tmpOut;

                mState = STATE_CONNECTED;

            }

            public void run() {

                Log.i(TAG, "BEGIN mConnectedThread");

                byte[] buffer = new byte[1024];

                int bytes;

                // Keep listening to the InputStream while connected

                while (mState == STATE_CONNECTED) {

                    try {

                        // Read from the InputStream

                        bytes = mmInStream.read(buffer);

                        // Send the obtained bytes to the UI Activity

                        mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)

                                .sendToTarget();

                    } catch (IOException e) {

                        Log.e(TAG, "disconnected", e);

                        connectionLost();

                        break;

                    }

                }

            }

            /**

            * Write to the connected OutStream.

            *

            * @param buffer The bytes to write

            */

            public void write(byte[] buffer) {

                try {

                    mmOutStream.write(buffer);

                    // Share the sent message back to the UI Activity

                    mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)

                            .sendToTarget();

                } catch (IOException e) {

                    Log.e(TAG, "Exception during write", e);

                }

            }

            public void cancel() {

                try {

                    mmSocket.close();

                } catch (IOException e) {

                    Log.e(TAG, "close() of connect socket failed", e);

                }

            }

        }

    }

    5.在主界面中调用

    初始化时候,若为null,则新建

            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

            // If the adapter is null, then Bluetooth is not supported

            if (mBluetoothAdapter == null) {

                Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();

                finish();

            }

            if (!mBluetoothAdapter.isEnabled()) {

                Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

                startActivityForResult(enableIntent, REQUEST_ENABLE_BT);

                // Otherwise, setup the chat session

            } else if (mChatService == null) {

                mChatService = new BluetoothChatService(this, mHandler);

            }

    试图建立连接

    private void connectDevice(Intent data, boolean secure) {

        // Get the device MAC address

        String address = data.getExtras()

                .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);

        // Get the BluetoothDevice object

        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

        // Attempt to connect to the device

        mChatService.connect(device, secure);

    }

    在onResume方法中启动

    if (mChatService != null) {

        // Only if the state is STATE_NONE, do we know that we haven't started already

        if (mChatService.getState() == BluetoothChatService.STATE_NONE) {

            // Start the Bluetooth chat services

            mChatService.start();

        }

    }

    发送消息给对面的蓝牙设备

    /**

        * Sends a message.

        *

        * @param message A string of text to send.

        */

        private void sendMessage(String message) {

            // Check that we're actually connected before trying anything

            if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {

                Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();

                return;

            }

            // Check that there's actually something to send

            if (message.length() > 0) {

                // Get the message bytes and tell the BluetoothChatService to write

                byte[] send = message.getBytes();

                mChatService.write(send);

            }

        }

    接收对面设备传回来的消息,用handler实现

    /**

        * The Handler that gets information back from the BluetoothChatService

        */

        private final Handler mHandler = new Handler() {

            @Override

            public void handleMessage(Message msg) {

                switch (msg.what) {

                    case Constants.MESSAGE_STATE_CHANGE:

                        switch (msg.arg1) {

                            case BluetoothChatService.STATE_CONNECTED:

                                //连接成功后返回

                                break;

                            case BluetoothChatService.STATE_CONNECTING:

                                //连接中

                                break;

                            case BluetoothChatService.STATE_LISTEN:

                            case BluetoothChatService.STATE_NONE:

                                //未连接

                                break;

                        }

                        break;

                    case Constants.MESSAGE_WRITE:

                        //传给对方的数据

                        break;

                    case Constants.MESSAGE_READ:

                        //从对方传回来的数据

                        break;

                    case Constants.MESSAGE_DEVICE_NAME:

                        //获取连接设备的设备名称

                        break;

                    case Constants.MESSAGE_TOAST:

                        //由于某种原因断开连接

                        break;

                }

            }

        };

    6.在onDestory中要关闭连接

    if (mChatService != null) {

        mChatService.stop();

    }

    以上。

    可以根据需求自定义蓝牙控制功能

    相关文章

      网友评论

          本文标题:蓝牙

          本文链接:https://www.haomeiwen.com/subject/yciivktx.html