蓝牙

1.添加蓝牙的使用权限

//管理蓝牙的权限

//使用蓝牙的权限

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

mBtAdapter = BluetoothAdapter.getDefaultAdapter();

Set 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();

}

以上。

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

你可能感兴趣的:(蓝牙)