Android蓝牙开发总结
一.蓝牙的使用环境:
版本的sdk才支持,模拟机上不能进行测试,需要在真机上进行测试。
2. Android的蓝牙一般常用有2.0和4.0两个版本:
版本:使用BlueZ协议栈
版本:使用全新的协议栈,可快速建立简单的链接。作为蓝牙1.0 – 3.0版本中蓝牙标准协议的替代方案。
因此4.0版本的蓝牙连接协议和连接方式和2.0的版本是不一样的!
二.蓝牙的开发过程:
1. 要操作蓝牙,先要在AndroidManifest.xml里加入权限:
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permissionandroid:name="android.permission.BLUETOOTH" />
2. 获取本地蓝牙适配器:
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
3. 打开蓝牙:
If (!mAdapter.isEnabled()) {
Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabler, REQUEST_ENABLE)};
搜索蓝牙设备:
1)mAdapter.startDiscovery();
2)定义BroadcastReceiver,用来取得搜索的远程蓝牙设备的信息:
BroadcastReceiver broadcastReceiver = new BlueBroadcastReceiver();
)创建过滤器,注册广播接收器,BluetoothReceiver接收广播。
//创建一个IntentFilter对象,将其action指定为BluetoothDevice.ACTION_FOUND
//IntentFilter它是一个过滤器,只有符合过滤器的Intent才会被我BluetoothReceive所接收
IntentFilter intent = new IntentFilter();
intent.addAction(BluetoothDevice.ACTION_FOUND);
// 用BroadcastReceiver来取得搜索结果
intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
intent.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//注册广播接收器 注册完后每次发送广播后,BluetoothReceiver就可以接收到这个广播
registerReceiver(broadcastReceiver, intent);
BroadcastReceiver接收到广播后,发现蓝牙设备,获取蓝牙设备的地址信息;
Class BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action=intent.getAction();
// 当发现蓝牙设备时
if(action.equals(BluetoothDevice.ACTION_FOUND)){
// 从Intent中获取蓝牙设备对象
//只要BluetoothReceiver接收到来自于系统的广播,这个广播是找到了 一个远程蓝牙设备
//Intent代表刚刚发现远程蓝牙设备适配器的对象,可以从收到的Intent对象取出一些信息
BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 添加蓝牙的名称和地址到listView中并显示列表
String str=(device.getName() + "|" + device.getAddress());
}
4)建立蓝牙连接:
A)通过远程蓝牙设备的地址来连接:
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
mBluetoothAdapter.cancelDiscovery();
B)服务器端(BluetoothServerSocket)和客户端(BluetoothSocket)指定同样UUID来连接:
1)服务器端:
BluetoothServerSocket serverSocket = mAdapter. listenUsingRfcommWithServiceRecord(serverSocketName,UUID);
serverSocket.accept();
2)客户端:
BluetoothSocket clienSocket=dcvice. createRfcommSocketToServiceRecord(UUID);
clienSocket.connect();
5)数据传递:
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
接收到的数据是字节流,又由于一般来说厂家给的协议都是十六进制数据,所以很多情况需要一个byte转十六进制String的函数:
public static String bytesToHex(byte[] bytes) {char[] hexChars = new char[bytes.length * 2];for ( int j = 0; j < bytes.length; j++ ) { int v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F];}return new String(hexChars);}
交换数据的方式:
发送一条协议的十六进制的数据给远程蓝牙设备,远程设备返回对应的数据,然后对接收到的字节流处理读取,提取我们需要的数据;
三.常用的蓝牙的类:
1.BluetoothAdapter 蓝牙适配器
BluetoothAdapter的常用方法:
cancelDiscovery() 取消发现,停止搜索设备
disable()关闭蓝牙
enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,
Intemtenabler=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);打开蓝牙,这个方法会弹出提示;
startActivityForResult(enabler,reCode);//同startActivity(enabler);
getAddress()获取本地蓝牙地址
getDefaultAdapter()获取默认BluetoothAdapter,
getName()获取本地蓝牙名称
getRemoteDevice(String address)根据蓝牙地址获取远程蓝牙设备
getState()获取本地蓝牙适配器当前状态(感觉可能调试的时候更需要)
isDiscovering()判断当前是否正在查找设备,是返回true
isEnabled()判断蓝牙是否打开,已打开返回true,否则,返回false
listenUsingRfcommWithServiceRecord(String name,UUID uuid)根据名称,UUID创建并返回BluetoothServerSocket,创建BluetoothSocket服务器端。
startDiscovery()开始搜索;
2.BluetoothDevice蓝牙设备:
createRfcommSocketToServiceRecord(UUIDuuid)根据UUID创建并返回一个BluetoothSocket,创建BluetoothSocket;BluetoothSocket这个类其他的方法,如getAddress(),getName(),同BluetoothAdapter一样;
getState() 蓝牙状态,只有在 BluetoothAdapter.STATE_ON 状态下才可以监听;
3.BluetoothServerSocket远程蓝牙设备,方法和Socket都差不多。
两个重载的accept(),accept(inttimeout)两者的区别在于后面的方法指定了过时时间,需要注意的是,执行这两个方法的时候,直到接收到了客户端的请求(或是过期之后),都会阻塞线程,应该放在新线程里运行!这两个方法都返回一个BluetoothSocket,最后的连接也是服务器端与客户端的两个BluetoothSocket的连接
close()关闭!
4.BluetoothSocket和BluetoothServerSocket客户端和服务端:
close(),关闭
connect()连接
getInptuStream()获取输入流
getOutputStream()获取输出流
getRemoteDevice()获取远程设备,获取bluetoothSocket指定连接的那个远程蓝牙设备