这么说不对,但是我觉得这么理解比较好理解,蓝牙分为重量级和轻量级,轻量级的连接是在蓝牙4.0以上才有的,也就是 BLE技术 , 而Android是在API 18 也就是4.3以上才支持蓝牙4.0技术。BLE更省电,连接速度更快,使用3个连接通道,而普通的蓝牙连接则使用了32个,下面就来介绍着两种方式。
重量级蓝牙
- BluetoothManager
- BluetoothAdapter
- BluetoothServiceSocket
- BluetoothSocket
不管是轻量级连接还是重量级连接,都需要这两个类Manager 和 Adapter,步骤是这样的:
1. 通过.getSystemService(Context.BLUETOOTH_SERVICE);得到Manager
2. 通过manager.getAdapter()得到adapter,
3. 通过adapter搜索。
4. 注册广播,来接收搜索到的设备信息。更多代码请看下面的连接,蓝牙一般使用。
打开蓝牙:
Intent enabler = new Intent(MyBluetoothAdapter.ACTION_REQUEST_ENABLE);
((Activity) mContext).startActivityForResult(enabler, 0x1);
注册广播:
BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//找到设备
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
}
}
}
之后就可以通过这个device来得到IO流,再具体的还是看下面的连接,蓝牙的一般使用。
BLE蓝牙
前两步和重量级连接一样,那个步骤,不同的是得到adapter之后,下面是具体代码:
/**
* 蓝牙管理模块
* Created by R on 2015/8/4.
*/
public class BluetoothManager {
private Context mContext;
/**
* 蓝牙适配器
*/
private BluetoothAdapter mAdapter;
/**
* BLE设备
*/
private BluetoothGatt mBluetoothGatt;
/**
* —————————————————————— 单例呀单例 ——————————————————————————
*/
private static BluetoothManager instance;
private BluetoothManager(Context context) {
mContext = context;
initBluetooth();
}
public static BluetoothManager getInstance(Context context) {
if (instance == null) {
synchronized (BluetoothManager.class) {
if (instance == null) {
if(context == null){
return null;
}
instance = new BluetoothManager(context);
}
}
}
return instance;
}
/**
* 初始化蓝牙
*/
private void initBluetooth() {
android.bluetooth.BluetoothManager manager = (android.bluetooth.BluetoothManager)mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mAdapter = manager.getAdapter();
}
/**
* 打开蓝牙
* @return
*/
public boolean openBluetooth() {
if (!isEnabled()) {
// Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
// ((Activity) mContext).startActivityForResult(enabler, 0x1);
return mAdapter.enable();
}
return false;
}
/**
* 关闭蓝牙
* @return
*/
public boolean closeBluetooth(){
if(isEnabled()){
return mAdapter.disable();
}
return false;
}
/**
* 开始搜索BLE设备
* @param callback
*/
public void startSearchOfLe(BluetoothAdapter.LeScanCallback callback){
if(!isEnabled()){
openBluetooth();
}
mAdapter.startLeScan(callback);
}
/**
* 停止搜索设备
*/
public void stopSearchOfLe(BluetoothAdapter.LeScanCallback callback) {
if (isEnabled()){
mAdapter.stopLeScan(callback);
}
}
/**
* 返回蓝牙是否可用
* @return
*/
public boolean isEnabled(){
return mAdapter.isEnabled();
}
/**
* 连接
*/
public void connectionOfGatt(BluetoothDevice device , BluetoothGattCallback callback){
if(device != null || callback == null){
mBluetoothGatt = device.connectGatt(mContext, true, callback);
}
}
public BluetoothGatt getGatt(){
return mBluetoothGatt;
}
}
这个代码其实没什么用,就是一些基本操作,关键在这里:
连接Gatt的步骤:
1. 打开蓝牙
2. 通过Manager拿到Adapter
3. 通过adapter搜索BLE设备,搜索的时候会让你传入一个LeScanCallback实现类用做回调。
4. 搜索到设备的时候,会去调用onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) 方法告诉你找到设备了。第一个参数是硬件设备,第二个是蓝牙距离,第三个是蓝牙的广播,比如说我们的产品就是吧一个16进制的SN号以byte[]写了进去。
5. 然后调用device.connectionGatt();连接BLE设备,这时你需要传入一个BluetoothGattCallback的实现类用作回调,这个回调就热闹了,具体的看API和参考博客, 在这里我只用到了onConnectionStateChange(BluetoothGatt gatt, int status, int newState) 、 onServicesDiscovered(BluetoothGatt gatt, int status)、onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) 方法。下面会详细说明。
6. 当你调用device.connectionGatt() 连接到设备之后,会回调onConnectionStateChange,他会返回一个Gatt对象,这个东西就相当于你的BLE设备了,其实到这里我也没搞清楚,因为按说就可以通过Gatt对象得到Service然后在得到BluetoothGattCharacteristic , 然后使用BluetoothGattCharacteristic的setValue()方法扔进去一个byte[]数组,再调用gatt.writeCharacteristic()吧之前的BluetoothGattCharacteristic扔进去就好了,但是不知道为什么我这里是获取不到Service的,必须要在onServicesDiscovered这个回调里才能得到Service。所以我是在onServicesDiscovered这个回调里完成上面步骤的。
7. 最后,当你完成上面步骤的时候,会有onCharacteristicWrite的回调,来告诉你是否写入成功了。
8. 接收数据,这个就简单了,做到这里就已经没什么挑战性了,就跟从初恋到老夫老妻了一样,自己去看onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,intstatus)这个方法吧,只要有消息都会去回调这个方法的,哦 还有,这之前别忘了先订阅一下:
BluetoothGattCharacteristic read = service.getCharacteristic(UUID.fromString(ConstantsOfBluetooth.UUID_READ));
参考链接
http://blog.csdn.net/wave_1102/article/details/39271693 这个好!!
http://blog.csdn.net/xubin341719/article/details/38584469 看不懂的蓝牙底层详解
http://www.cnblogs.com/freeliver54/archive/2011/12/13/2285980.html 蓝牙一般使用
http://www.2cto.com/kf/201411/349575.html 蓝牙4.0总结
http://blog.csdn.net/woshasanguo/article/details/41082395 BLE蓝牙连接参考的是这个
http://www.cnblogs.com/freeliver54/archive/2011/12/13/2285980.html
http://www.open-open.com/lib/view/open1390879771695.html#_label8 相当于中文API了