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

来源:互联网 发布:怎么提升淘宝排名 编辑:程序博客网 时间:2024/05/24 03:52

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

先贴一张自制的uml图:


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

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

(1)增加成员变量:

//获取消息的Handler

Handler mHandler;

//蓝牙模块

//待连接的蓝牙名称

         publicstatic final String BLUETOOTH_NAME = "XXXX";

         //连接 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,记得要改一下连接的蓝牙地址或者名称!

1 0
原创粉丝点击