android 蓝牙模块Bluetooth 使用 十六进制数据发送

一个蓝牙模块看起来很小,弄起来还是有点复杂的,从网上找了一个示例代码,http://blog.csdn.net/vnanyesheshou/article/details/51554852但是不能直接用,需要自己进行阅读理解和修改后才能使用。

先贴一张自制的uml图:


从图中不难看出涉及的类还是挺多的,大致上分为设备初始化、建立连接、发送消息三个大致的步骤吧。网上的代码封装成了一个BluetoothChatUtil实用的类,负责建立通信和发送消息,然后通过消息的方式让界面显示获取到的数据。BroadcastReceiver负责接收蓝牙扫描时获取到的设备,由于项目中的目标蓝牙是已经绑定的,所以直接使用BluetoothAdapter类的getBondedDevices()函数来获取已经绑定的蓝牙设备,然后通过设定名称或者地址来进行连接。

为现有项目添加蓝牙模块的步骤大致如下(简单地从代码出发):

(1)增加成员变量:

//获取消息的Handler

Handler mHandler;

//蓝牙模块

//待连接的蓝牙名称

         publicstatic final String BLUETOOTH_NAME = "XXXX";

扫描二维码关注公众号,回复: 3833169 查看本文章

         //连接 msg

         publicstatic final String OPEN_BLUE_HEX_STRING = "00 00 00 00 ";

         //关闭 msg

         publicstatic final String CLOSE_BLUE_HEX_STRING = "FF FF FF FF";

         //待连接的蓝牙地址

         privateString mBluetoothAddress = "XX:XX:XX:XX:XX:XX";

    boolean hasregister = false;

    private ProgressDialog mProgressDialog;

    //蓝牙通信模块

         privateBluetoothChatUtil mBlthChatUtil;

         //当前activity的句柄

         privateContext mContext;

         privateint REQUEST_ENABLE_BT = 1;

(2)onCreate中初始化:

mContext = this;

         mProgressDialog= new ProgressDialog(this);

         在handleMessage(Message msg)中捕获几个消息:

        //连接成功

 caseBluetoothChatUtil.STATE_CONNECTED:

                 if(mProgressDialog.isShowing()){

                        mProgressDialog.dismiss();

                 }

                 StringdeviceName = msg.getData().getString(BluetoothChatUtil.DEVICE_NAME);

                 //mBtnBluetoothConnect.setText("已成功连接到设备"+ deviceName);

                 Toast.makeText(getApplicationContext(),"连接成功:"+deviceName, Toast.LENGTH_SHORT).show();

 //连接后就发送你需要发送的消息

                 sendBluetoothMessage(OPEN_BLUE_HEX_STRING);

                  break;      

//连接失败                            

         caseBluetoothChatUtil.STATAE_CONNECT_FAILURE:

                 if(mProgressDialog.isShowing()){

                  mProgressDialog.dismiss();

                  }

        Toast.makeText(getApplicationContext(),"连接失败", Toast.LENGTH_SHORT).show();

          break;

//断开连接

      caseBluetoothChatUtil.MESSAGE_DISCONNECTED:

                 if(mProgressDialog.isShowing()){

                        mProgressDialog.dismiss();

                 }

          //mBtnBluetoothConnect.setText("与设备断开连接");

                break;

//收到消息

        caseBluetoothChatUtil.MESSAGE_READ:

                byte[]buf = msg.getData().getByteArray(BluetoothChatUtil.READ_MSG);

                Stringstr = new String(buf,0,buf.length);

               Toast.makeText(getApplicationContext(),"读成功" + str, Toast.LENGTH_SHORT).show();

                break;

         实例化通信模块,并连接蓝牙:

//蓝牙模块

                   mBlthChatUtil= BluetoothChatUtil.getInstance(mContext);

                   mBlthChatUtil.registerHandler(mHandler);

                   initBluetooth();

//根据自己的需求来选择需不需要扫描设备

        //mBluetoothAdapter.startDiscovery();

//连接设备

        connect();

        if (mBlthChatUtil.getState() == BluetoothChatUtil.STATE_NONE) {

                            //启动蓝牙聊天服务

                            mBlthChatUtil.start();

                  }

               蓝牙初始化函数initBluetooth()和connect函数:

private void initBluetooth() {

                      mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();

                     if(mBluetoothAdapter == null) {//设备不支持蓝牙

                            Toast.makeText(getApplicationContext(),"设备不支持蓝牙", Toast.LENGTH_LONG).show();

                            finish();

                            return;

                   }

                   //判断蓝牙是否开启

                   if(!mBluetoothAdapter.isEnabled()) {//蓝牙未开启

                            IntentenableIntent = new Intent(

                                               BluetoothAdapter.ACTION_REQUEST_ENABLE);

                            startActivityForResult(enableIntent,REQUEST_ENABLE_BT);

                            //开启蓝牙

                            mBluetoothAdapter.enable();

                   }                          

                   //

                   IntentFilterfilter = new IntentFilter();

                   filter.addAction(BluetoothDevice.ACTION_FOUND);

                   filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

                   //registerReceiver(mBluetoothReceiver,filter);

                   //hasregister= true;

                   if(mBluetoothAdapter.isEnabled()) {

                            intnMode = mBluetoothAdapter.getScanMode();

                            if(nMode== BluetoothAdapter.SCAN_MODE_CONNECTABLE){

                                     Log.e(TAG_BLUE,"getScanMode= SCAN_MODE_CONNECTABLE");

                            }

                            if(nMode== BluetoothAdapter.SCAN_MODE_NONE){

                                     Log.e(TAG_BLUE,"getScanMode= SCAN_MODE_NONE");

                            }

                            if(nMode== BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){

                                     Log.e(TAG_BLUE,"getScanMode= SCAN_MODE_CONNECTABLE_DISCOVERABLE");

                            }

                         //if(nMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {

                         //     IntentdiscoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

                         /       discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);

                         //       startActivity(discoverableIntent);

                         //}

                   }

                   //本身蓝牙的名称和地址

                   Stringname = mBluetoothAdapter.getName();

                   Stringaddress = mBluetoothAdapter.getAddress();

                   Log.d(TAG_BLUE,"bluetoothname ="+name+" address ="+address);

         }

         publicvoid connect() {

                   Set<BluetoothDevice>device = mBluetoothAdapter.getBondedDevices(); 

       

       if(device.size()>0){ //存在已经配对过的蓝牙设备 

           for(Iterator<BluetoothDevice>it=device.iterator();it.hasNext();){ 

                BluetoothDevicebtd=it.next(); 

                String name = btd.getName();

                String address =btd.getAddress();

                String nameString =btd.getName()+'\n'+btd.getAddress(); 

               Log.e(TAG_BLUE,"getBondedDevices :" + nameString);

                //if(name != null &&name.equals(BLUETOOTH_NAME)){

                if(address != null &&address.equals(mBluetoothAddress)){

                         mBlthChatUtil.connect(btd);

                         break;

                                               //Toast.makeText(mContext,"连接成功", Toast.LENGTH_SHORT).show();

                }

           } 

       }else{  //不存在已经配对过的蓝牙设备 

                Log.e(TAG,"No can bematched to use bluetooth"); 

       } 

}

十六进制数据转换HexCommandtoByte和消息发送函数sendBluetoothMessage

//  十六进制的字符串转换成byte数组     

    public static byte[]HexCommandtoByte(byte[] data) { 

            if (data == null) { 

                return null; 

            } 

            int nLength = data.length;  

              

            String strTemString = new String(data, 0, nLength); 

            String[] strings = strTemString.split(" "); 

            nLength = strings.length; 

            data = new byte[nLength];            

            for (int i = 0; i < nLength; i++) { 

                if (strings[i].length() != 2) { 

                     data[i] = 00; 

                     continue; 

                } 

                try { 

                     data[i] =(byte)Integer.parseInt(strings[i], 16); 

                } catch (Exception e) { 

                     data[i] = 00; 

                     continue; 

                } 

            } 

            return data; 

         }

         public void sendBluetoothMessage(Stringmessagesend){

                   Log.e(TAG_BLUE,"sendmessage : " + messagesend);

                   byte[] sendByte =HexCommandtoByte(messagesend.getBytes());

                   //mBlthChatUtil.write(messagesend.getBytes());

                   mBlthChatUtil.write(sendByte);

         }

(3)在返回onBackPressed()或者onDestroy()发送关闭蓝牙消息,并注销蓝牙:

//关闭

       sendBluetoothMessage(CLOSE_BLUE_HEX_STRING);

        if(mBluetoothAdapter!=null &&mBluetoothAdapter.isDiscovering()){ 

                 mBluetoothAdapter.cancelDiscovery(); 

        } 

       

        if (mBlthChatUtil.getState() !=BluetoothChatUtil.STATE_CONNECTED) {

                            Toast.makeText(mContext,"蓝牙未连接", Toast.LENGTH_SHORT).show();

                   }else {

                            mBlthChatUtil.stop();

                   }

BluetoothChatUtil.java内容如下:

package XXX;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

/**
 这类做所有的工作,建立和管理蓝牙
*连接其他装置。它有一个线程,监听
*传入连接,螺纹连接装置,和一个
*执行数据传输线连接时。
 */
public class BluetoothChatUtil {
    // 调试
    private static final String TAG = "BluetoothChatService";
    private static final boolean D = true;

    // 名社民党记录当创建服务器套接字
    private static final String NAME = "BluetoothChat";
    									 				
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
	public static StringBuffer hexString = new StringBuffer();
    // 适配器成员
    private final BluetoothAdapter mAdapter;
    private Handler mHandler;
    private AcceptThread mAcceptThread;
    private ConnectThread mConnectThread;
    private ConnectedThread mConnectedThread;
    private int mState;
	private static BluetoothChatUtil mBluetoothChatUtil;
	private BluetoothDevice mConnectedBluetoothDevice;
    //常数,指示当前的连接状态
    public static final int STATE_NONE = 0;       // 当前没有可用的连接
    public static final int STATE_LISTEN = 1;     // 现在侦听传入的连接
    public static final int STATE_CONNECTING = 2; // 现在开始传出联系
    public static final int STATE_CONNECTED = 3;  // 现在连接到远程设备
    public static final int STATAE_CONNECT_FAILURE = 4;
    public static boolean bRun = true;
    public static final int MESSAGE_DISCONNECTED = 5;
    public static final int STATE_CHANGE = 6;
    public static final String DEVICE_NAME = "device_name";
    public static final int MESSAGE_READ = 7;
    public static final int MESSAGE_WRITE= 8;
    public static final String READ_MSG = "read_msg";
    /**
     * 构造函数。准备一个新的bluetoothchat会话。
     * @param context  用户界面活动的背景
     */
    private BluetoothChatUtil(Context context) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mState = STATE_NONE;       
    }

    public static BluetoothChatUtil getInstance(Context c){
    	if(null == mBluetoothChatUtil){
    		mBluetoothChatUtil = new BluetoothChatUtil(c);
    	}
    	return mBluetoothChatUtil;
    }
    public void registerHandler(Handler handler){
    	mHandler = handler;
    }
    
    public void unregisterHandler(){
    	mHandler = null;
    }
    /**
     * 设置当前状态的聊天连接
     * @param state  整数定义当前连接状态
     */
    private synchronized void setState(int state) {
        if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
        mState = state;
        // 给新状态的处理程序,界面活性可以更新
        mHandler.obtainMessage(STATE_CHANGE, state, -1).sendToTarget();
    }

    /**
     * 返回当前的连接状态。 */
    public synchronized int getState() {
        return mState;
    }
    
    public BluetoothDevice getConnectedDevice(){
    	return mConnectedBluetoothDevice;
    }
    /**
     * 开始聊天服务。特别acceptthread开始    开始
     * 会话听力(服务器)模式。所谓的活动onresume() */
    public synchronized void start() {
        if (D) Log.d(TAG, "start");
        //取消任何线程试图建立连接
        if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
        // 取消任何线程正在运行的连接
        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
        // 启动线程来听一个bluetoothserversocket
        if (mAcceptThread == null) {
            mAcceptThread = new AcceptThread();
            mAcceptThread.start();
        }
        setState(STATE_LISTEN);
    }
   
    //连接按键响应函数
    /**
     * 开始connectthread启动连接到远程设备。
     * @param 装置连接的蓝牙设备
     */
    public synchronized void connect(BluetoothDevice device) {
        if (D) Log.d(TAG, "connect to: " + device);
        // 取消任何线程试图建立连接
        if (mState == STATE_CONNECTING) {
            if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
        }
        // 取消任何线程正在运行的连接
        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

        //启动线程连接的设备
        mConnectThread = new ConnectThread(device);
        mConnectThread.start();
        setState(STATE_CONNECTING);
    }

    /**
     * 开始connectedthread开始管理一个蓝牙连接
     * @param bluetoothsocket插座上连接了
     * @param 设备已连接的蓝牙设备
     */
    @SuppressWarnings("unused")
	public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
        if (D) Log.d(TAG, "connected");
        // 取消线程完成连接
        if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
        //取消任何线程正在运行的连接
        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

        // 取消接受线程只因为我们要连接到一个设备
        if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}

        // 启动线程管理连接和传输
        mConnectedThread = new ConnectedThread(socket);
        mConnectedThread.start();
        //把名字的连接设备到Activity
        mConnectedBluetoothDevice =  device;
        Message msg = mHandler.obtainMessage(STATE_CONNECTED);
        Bundle bundle = new Bundle();
        bundle.putString(DEVICE_NAME, device.getName());
        msg.setData(bundle);
        mHandler.sendMessage(msg);
        setState(STATE_CONNECTED);
       }

    /**
     * 停止所有的线程
     */
    public synchronized void stop() {
        if (D) Log.d(TAG, "stop");
        if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
        if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
        setState(STATE_NONE);
        //start();
    }

    /**
     * Write to the ConnectedThread in an unsynchronized manner
     * @param out The bytes to write
     * @see ConnectedThread#write(byte[])
     */
    public void write(byte[] out) {
        //创建临时对象
        ConnectedThread r;
        // 同步副本的connectedthread
        synchronized (this) {
            if (mState != STATE_CONNECTED) return;
            r = mConnectedThread;
        }
        // 执行写同步
        r.write(out);
    }

    /**
     * Indicate that the connection attempt failed and notify the UI Activity.
     */
    private void connectionFailed() {
        setState(STATE_LISTEN);
        // 发送失败的信息带回活动
        Message msg = mHandler.obtainMessage(STATAE_CONNECT_FAILURE);
        mHandler.sendMessage(msg);
        mConnectedBluetoothDevice = null;
    }

    /**
     * Indicate that the connection was lost and notify the UI Activity.
     */
    private void connectionLost() {
        setState(STATE_LISTEN);
        // 发送失败的信息带回Activity
        Message msg = mHandler.obtainMessage(MESSAGE_DISCONNECTED);
        mHandler.sendMessage(msg);
        mConnectedBluetoothDevice = null;
        stop();
    }

    /**
    *本线同时侦听传入的连接。它的行为
    *喜欢一个服务器端的客户端。它运行直到连接被接受
    *(或取消)。
     */
    private class AcceptThread extends Thread {
        // 本地服务器套接字
        private final BluetoothServerSocket mServerSocket;
        public AcceptThread() {       	
            BluetoothServerSocket tmp = null;
            // 创建一个新的侦听服务器套接字
            try {
                tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
            } catch (IOException e) {
                Log.e(TAG, "listen() failed", e);
            }
            mServerSocket = tmp;
        }

        public void run() {
            if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
            setName("AcceptThread");
            BluetoothSocket socket = null;
            // 循环,直到连接成功
            while (mState != STATE_CONNECTED) {
                try {
                    // 这是一个阻塞调用和将只返回一个
                    // 成功的连接或例外
                    socket = mServerSocket.accept();
                } catch (IOException e) {
                    Log.e(TAG, "accept() failed", e);
                    break;
                }
                // 如果连接被接受
                if (socket != null) {
                    synchronized (BluetoothChatUtil.this) {
                        switch (mState) {
                        case STATE_LISTEN:
                        case STATE_CONNECTING:
                            // 正常情况。启动连接螺纹。
                            connected(socket, socket.getRemoteDevice());
                            break;
                        case STATE_NONE:
                        case STATE_CONNECTED:
                            // 没有准备或已连接。新插座终止。
                            try {
                                socket.close();
                            } catch (IOException e) {
                                Log.e(TAG, "Could not close unwanted socket", e);
                            }
                            break;
                        }
                    }
                }
            }
            if (D) Log.i(TAG, "END mAcceptThread");
        }

        public void cancel() {
            if (D) Log.d(TAG, "cancel " + this);
            try {
                mServerSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "close() of server failed", e);
            }
        }
    }


    /**
     * 本线在试图使传出联系
     *与设备。它径直穿过连接;或者
     *成功或失败。
     */
    private class ConnectThread extends Thread {
        private BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
        public ConnectThread(BluetoothDevice device) {
            mmDevice = device;
            BluetoothSocket tmp = null;
            // 得到一个bluetoothsocket
            try {
            	mmSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                Log.e(TAG, "create() failed", e);
                mmSocket = null;
            }
        }

        public void run() {
            Log.i(TAG, "BEGIN mConnectThread");
            setName("ConnectThread");
            mAdapter.cancelDiscovery();
            // 使一个连接到bluetoothsocket
            try {
                // socket 连接
                mmSocket.connect();
            } catch (IOException e) {
                connectionFailed();
                //关闭这个socket
                try {
                    mmSocket.close();
                } catch (IOException e2) {
                    Log.e(TAG, "unable to close() socket during connection failure", e2);
                }
                // 启动服务在重新启动聆听模式
                BluetoothChatUtil.this.start();
                return;
            }
            // 因为我们所做的connectthread复位
            synchronized (BluetoothChatUtil.this) {
                mConnectThread = null;
            }
            // 启动连接线程
            connected(mmSocket, mmDevice);
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "close() of connect socket failed", e);
            }
        }
    }

    /**
     * 本线在连接与远程设备。
     * 它处理所有传入和传出的传输。
     */
    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        
        public ConnectedThread(BluetoothSocket socket) {
            Log.d(TAG, "create ConnectedThread");
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            // 获得bluetoothsocket输入输出流
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.e(TAG, "没有创建临时sockets", e);
            }
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }  
       
        public void run() {
            Log.i(TAG, "BEGIN mConnectedThread");
            int bytes;
            // 继续听InputStream同时连接
            while (true) {
                try {
                	 byte[] buffer = new byte[1024];
                    // 读取输入流
                    bytes = mmInStream.read(buffer);

                    // 发送获得的字节的用户界面
                    Message msg = mHandler.obtainMessage(MESSAGE_READ);
                    Bundle bundle = new Bundle();
                    bundle.putByteArray(READ_MSG, buffer);
                    msg.setData(bundle);
                    mHandler.sendMessage(msg);          
                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    break;
                }
            }
       }
        /**
         * 写输出的连接。
         * @param buffer  这是一个字节流
         */
        public void write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);
                // 分享发送的信息到Activity
                mHandler.obtainMessage(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);
            }
        }
    }
}


自己修改后的代码下载地址是:http://download.csdn.net/detail/u200814342a/9839396,记得要改一下连接的蓝牙地址或者名称!

猜你喜欢

转载自blog.csdn.net/u200814342A/article/details/71603451