Android(Java)开发之获取BLE广播包(扫描后获取:广播数据+扫描应答数据+RSSI)
来源:互联网 发布:中国石油大学网络教育 编辑:程序博客网 时间:2024/06/08 08:41
一、安卓BLE的广播包数据从哪获取?
通常,安卓APP读写BLE设备的数据都是建立连接后通过GATT获取或修改。但是,BLE设备向外广播时本身会携带一部分有用信息,如将传感数据存放到广播包的自定义数据段,最近接触的一个iBeacon/EddyStone整合项目便是类似,因此为了提取广播包进行解析,首要问题就是安卓APP如何获取广播数据。
其实,安卓蓝牙在扫描设备后,回调方法 onLeScan(...)中的参数 scanRecord 就是广播数据,这里同时包含广播数据和扫描应答数据(均为31字节),所以长度一般就是 62 字节,BLE4.0规定,如果广播包和扫描应答包不足字节,则以0补齐。如下:
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) { ...//scanRecord存放广播和扫描应答数据,rssi存放扫描获取的rssi值 } };
二、如何存储广播包数据并解析?
1.目标:扫描的设备显示List中除了显示设备名、Mac地址外,还加入完整的scanRecord数据包显示和rssi的显示。
2.步骤:(基于官方BLE Demo)
(1)在ListView的适配器创建中加入RSSI和Record列表
//ListView Adapter,用于在listview里管理扫描到的设备 private class LeDeviceListAdapter extends BaseAdapter { private ArrayList<BluetoothDevice> mLeDevices; private ArrayList<Integer> mRSSIs;//新加 private ArrayList<byte[]> mRecords;//新加 private LayoutInflater mInflator; public LeDeviceListAdapter() { super(); mLeDevices = new ArrayList<BluetoothDevice>(); mRSSIs = new ArrayList<Integer>();//新加 mRecords = new ArrayList<byte[]>();//新加 mInflator = DeviceScanActivity.this.getLayoutInflater(); } ...}
(2)改写LeDeviceListAdapter适配器中的addDevice方法
public void addDevice(BluetoothDevice device,int rssi,byte[] scanRecord) { if(!mLeDevices.contains(device)) { mLeDevices.add(device); mRSSIs.add(rssi);//新加 mRecords.add(scanRecord);//新加 } }
// Device scan callback. private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) { runOnUiThread(new Runnable() { @Override public void run() { mLeDeviceListAdapter.addDevice(device,rssi,scanRecord); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } }
static class ViewHolder { TextView deviceName; TextView deviceAddress; TextView deviceBroadcastPack;//加入广播包数据 TextView deviceRssi;//加入RSSI }
@Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder viewHolder; // General ListView optimization code. if (view == null) { view = mInflator.inflate(R.layout.listitem_device, null); viewHolder = new ViewHolder(); viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address); viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name); viewHolder.deviceBroadcastPack = (TextView) view.findViewById(R.id.device_broadcastPack); viewHolder.deviceRssi = (TextView) view.findViewById(R.id.device_rssi); view.setTag(viewHolder); } else { viewHolder = (ViewHolder) view.getTag(); } //获取设备列表、RSSI列表和广播包列表项目 BluetoothDevice device = mLeDevices.get(i); int rssi = mRSSIs.get(i); byte[] scanRecord = mRecords.get(i); //提取信息 final String deviceName = "设备名:" + device.getName(); final String deviceAddr = "Mac地址:" + device.getAddress(); final String broadcastPack ="广播包:" + bytesToHex(scanRecord);//此处调用了格式转换方法bytesToHex()将十六进制序列转String final String rssiString = "RSSI:" + String.valueOf(rssi) + "dB";//此处调用了String的格式转换方法valueOf()将数值类型转String //显示数据 if (deviceName != null && deviceName.length() > 0)//显示设备名 viewHolder.deviceName.setText(deviceName); else viewHolder.deviceName.setText(R.string.unknown_device); viewHolder.deviceAddress.setText(deviceAddr);//显示设备地址 viewHolder.deviceBroadcastPack.setText(broadcastPack);//显示广播包 viewHolder.deviceRssi.setText(rssiString);//显示RSSI return view; }
(5)实现scanRecord的格式转换方法:bytesToHex()---广播和扫描应答数据以十六进制格式存储在bytes[]数组中,需要转换为String后显示
//scanRecords的格式转换 static final char[] hexArray = "0123456789ABCDEF".toCharArray(); private 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); }
三、效果展示
实现的基本效果如图,扫描到的设备列表加入了RSSI和完整广播包的显示
后注:获取到scanRecord后就能根据协议解析广播包了,根据需求提取对应字段。scanRecord的数据必须进行格式转换,否则列表显示会出现乱码,格式不匹配!
2 0
- Android(Java)开发之获取BLE广播包(扫描后获取:广播数据+扫描应答数据+RSSI)
- 【BLE】CC2541之主机端获取广播包数据
- 【BLE-CC2640】CC2640之主机端获取广播包数据
- Android 获取USB扫描枪扫描数据(无界面)
- CC2541解析广播数据及扫描响应
- Android蓝牙BLE之RSSI数据的读写(1)
- Android蓝牙BLE之RSSI数据的读写(1)
- BLE 广播数据解析
- BLE 广播数据解析
- BLE 广播数据解析
- 蓝牙BLE 广播数据
- BLE 广播数据解析
- BLE 广播数据解析
- android BLE蓝牙RSSI数据的读写
- android设备连接蓝牙扫描枪获取数据
- Java串口通信 ----> 扫描标签获取数据存入数据库
- java获取扫描枪的数据到数据库
- 广播包数据含义
- 纯虚函数
- notepad++ 使用
- iOS 带缓存,带网络监控的数据请求
- day03-模拟手机短信发送
- Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化(一)
- Android(Java)开发之获取BLE广播包(扫描后获取:广播数据+扫描应答数据+RSSI)
- ELK结合Spark构建高可用架构及监控spark集群
- Ubuntu安装Linux网页版微信
- cannot find -lcudart
- <转>Spark-Mllib 数据类型
- 设计模式之单例模式-java
- Unsupported major.minor version 52.0
- Mysql5.7 的错误日志中最常见的note级别日志解释
- 双链表的建立、测长、打印、删除、插入