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);
以上是关于android 蓝牙模块Bluetooth 使用 十六进制数据发送的主要内容,如果未能解决你的问题,请参考以下文章
Android4.42-Settings源代码分析之蓝牙模块Bluetooth总体实现(总)
android 蓝牙模块Bluetooth 使用 十六进制数据发送