有关Android Bluetooth/蓝牙的介绍
来源:互联网 发布:mac有没有软件助手 编辑:程序博客网 时间:2024/05/01 01:41
最近在做android bluetooth方面的项目,在网上找了很多所谓的demo和官方的demo。发现或多或少的都有些问题,今天是第一次写技术方面的文章,我就从这篇开始吧!
关于android bluetooth 无非就是三点:
一. 扫描蓝牙 二. 连接蓝牙设备 三. 通信。
下面让我们就同第一点开始:
android蓝牙的扫描有三种函数:
1.public boolean startDiscovery();
2.public boolean startLeScan(LeScanCallback callback)和 public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback)。
这两张函数都是在BluethoothAdapter这个类中。下面我们就来解释下这两个函数:
public boolean startDiscovery()这个函数只能扫描传统意义的蓝牙设备 时间扫描12s自动关闭,这是异步操作扫描蓝牙设备。首先你要注册一个接收者。
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
//广播接收者
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
}
}
}
};
当然还有其他的广播事件你也可以注册。请自己查看SDK。
public boolean startLeScan(LeScanCallback callback)和 public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback)这两个函数是扫描低功耗蓝牙设备的,好像没有扫描时间限制,只能调用public void stopLeScan(LeScanCallback callback)来关闭。这个两个不同的地方就是可以过滤你想要扫描的UUID,他们都是通过的LeScanCallback回调接口来返回扫描的结果。
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() { @Override public void run() { LogUtil.d(TAG, device.getAddress()+" LeScanCallback:::"+device.getName()); if (!mArrayList.contains(device)) { mArrayList.add(device); mDeviceAdapter.notifyDataSetChanged(); } } }); } };
但是这种扫描低功耗蓝牙的方法在api21就被标记废弃使用。下面介绍第三扫描蓝牙设备的函数:
3.public void startScan(final ScanCallback callback)和public void startScan(List filters, ScanSettings settings, final ScanCallback callback)这连个函数和第二差不多,区别是这个是用来代替第二个的,函数在BluetoothLeScanner类中。mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();也都是通过ScanCallBack的回调来处理函数结果的。区别是后面一个是用来过滤你想要扫描到低功耗蓝牙设备。至于怎么去过滤我还没去研究,可以自行看sdk和网上早资料。该动手的时候还是的自己来!有关android 蓝牙扫描就到这里了下面讲连接蓝牙设备。
第二点 蓝牙的连接:
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport),扫描到结果后会得到BluetoothDevice。而这个函数恰好是在BluetoothDevice类中。调用它就可以连接蓝牙设备了,其中一个参数是BluetoothGattCallback这个回调函数中有:
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {}public void onServicesDiscovered(BluetoothGatt gatt, int status) {}public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {}public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {}public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {}public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {}public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {}public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {}public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {}public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {}
这里面有多个函数的回调处理结果。当你连接成功或断开后会回调onConnectionStateChange();而onServicesDiscovered()的这个函数的回调要主动请求的。
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED){
gatt.discoverServices();}
调用粗体的函数后才会触发onServicesDiscovered(BluetoothGatt gatt, int status) 。onServicesDiscovered(BluetoothGatt gatt, int status) 的作用是发现蓝牙可用的services,List list = gatt.getServices();会获取到所有services。一个蓝牙设备会有多个services,一个service会有多个BluetoothGattCharacteristic,一个BluetoothGattCharacteristic会有多个BluetoothGattDescriptor:
public void setService(final BluetoothGatt gatt){ List<BluetoothGattService> list = gatt.getServices(); List<BluetoothGattCharacteristic> mCharacteristics; List<BluetoothGattDescriptor> mDescriptors; if (list.size()>0){ for (BluetoothGattService service : list){ int type = service.getType(); if (service.getUuid().toString().equalsIgnoreCase(SERUUID_STR.toString())){ LogUtil.e(TAG, "-->BluetoothGattService uuid:" + service.getUuid()); LogUtil.e(TAG, "-->BluetoothGattService value:" + service.getType()); mCharacteristics = service.getCharacteristics(); for (BluetoothGattCharacteristic characteristic : mCharacteristics){ if (characteristic.getUuid().toString().equalsIgnoreCase(WRITE_UUID.toString())){ LogUtil.e(TAG, "-->characteristic write uuid:" + characteristic.getUuid()); LogUtil.e(TAG, "-->characteristic value:" + characteristic.getValue()); LogUtil.e(TAG, "-->characteristic getProperties:" + characteristic.getProperties()); LogUtil.e(TAG, "-->characteristic getPermissions:" + characteristic.getPermissions()); write_characteristic = characteristic; **setCharacteristicNotification**(write_characteristic,true); } else if(characteristic.getUuid().toString().equalsIgnoreCase(READ_UUID.toString())){ LogUtil.e(TAG, "-->characteristic write uuid:" + characteristic.getUuid()); LogUtil.e(TAG, "-->characteristic value:" + characteristic.getValue()); LogUtil.e(TAG, "-->characteristic getProperties:" + characteristic.getProperties()); LogUtil.e(TAG, "-->characteristic getPermissions:" + characteristic.getPermissions()); read_characteristic = characteristic; **setCharacteristicNotification**(read_characteristic,true); readCharacteristic(read_characteristic); } mDescriptors = characteristic.getDescriptors(); for (BluetoothGattDescriptor descriptor : mDescriptors){ LogUtil.e(TAG, "-->BluetoothGattDescriptor uuid:" + descriptor.getUuid()); LogUtil.e(TAG, "-->BluetoothGattDescriptor value:" + descriptor.getValue()); LogUtil.e(TAG, "-->BluetoothGattDescriptor getPermissions:" + descriptor.getPermissions()); } } } } }
以上都是android蓝牙链接蓝牙设备的介绍。
第三点 蓝牙之间的通信:
在上面你可以获取到所有的BluetoothGattService,BluetoothGattCharacteristic,
BluetoothGattDescriptor。通过设置BluetoothGattCharacteristic的setCharacteristicNotification(read_characteristic,true)来达到数据交换。每一个BluetoothGattCharacteristic都有个UUID和属性是通过蓝牙文档来了解每个BluetoothGattCharacteristic的读,写,提醒等属性来进行数据交换。会触发BluetoothGattCallback这个回调函数中的读写提醒等回调函数的回调,然后你就可以获取读写的数据了。
下面在写下在android蓝牙开发中应该注意的一些问题,希望对看到的人有点帮助:
1.权限的问题
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 第三个权限是在有的机型上面需要获取位置信息才能扫描的。 在sdk 23上面版本的时候需要 代码获取位置权限 private boolean mayRequestLocation() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } if (checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { return true; } else { LogUtil.d(TAG,"REQUEST PERMISSION"); requestPermissions(new String[]{permission}, REQUEST_FINE_LOCATION); } return false;}要不然你很有可能扫不到蓝牙设备。
2.数据读写问题
楼主在写入数据的时候会出现数据丢失,蓝牙设备有时候会丢失一段数据,据楼主观察是写入数据的时候太快的问题,但我在写入数据时候稍微延迟300ms的时候会好很多。具体楼主觉得写入太快导致。
3.demo问题
请不要让我发demo,如需要参考你参考android sdk中有关于蓝牙的两个demo 一个是 bluetoothchat 这是用蓝牙实现聊天的demo用的bluetoothSocket实现的。还有一个低功耗的bluetoothLeGatt的demo。大家可以去了解下,多动手多动脑多犯错!
- 有关Android Bluetooth/蓝牙的介绍
- Bluetooth(蓝牙)有关术语
- Bluetooth: (蓝牙)有关术语
- Bluetooth--- android -- 蓝牙 bluetooth
- BlueTooth: 蓝牙介绍
- Bluetooth---Android蓝牙4.0的数据通讯
- Bluetooth---Android的蓝牙聊天示例应用程序
- android Bluetooth的实现蓝牙操作
- Android的蓝牙串口(Bluetooth SPP)使用
- android 蓝牙bluetooth的简单使用
- 有关Android Bluetooth--Bluetooth基础
- 有关Android Bluetooth--Bluetooth基础
- android bluetooth蓝牙移植
- Android BlueTooth蓝牙通信
- android -- 蓝牙 bluetooth 入门
- [Android]蓝牙bluetooth
- android 蓝牙 通信 bluetooth
- android -- 蓝牙 bluetooth解读
- Ionic Framework 说明书
- Yii 2.0 使用笔记
- 欢迎使用CSDN-markdown编辑器
- 关于递归的初步理解
- Jetty9.2开始之路
- 有关Android Bluetooth/蓝牙的介绍
- Android 快速开发系列 ORMLite 框架最佳实践
- C/C++之define用法小结
- HDFS
- Eclipse闪退/打不开/无法启动/一闪而过
- [leetcode] 【链表】141. Linked List Cycle
- 电器组装行业ERP解决方案
- 敲php的日子
- Gradle build设置自动log开关