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

Posted 小田田_XOW

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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";

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

以上是关于android 蓝牙模块Bluetooth 使用 十六进制数据发送的主要内容,如果未能解决你的问题,请参考以下文章

Android4.42-Settings源代码分析之蓝牙模块Bluetooth总体实现(总)

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

Android4.42-Settings源码分析之蓝牙模块Bluetooth(上)

Android开发之蓝牙(Bluetooth)

Android蓝牙技术Bluetooth初体验

Android蓝牙技术Bluetooth使用流程(详解)