123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- package com.elinkthings.ailinksecrettooldemo;
-
- import android.os.ParcelUuid;
-
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- /**
- * xing<br>
- * 2019/3/7<br>
- * 广播解析工具类
- */
- public class BleBroadcastUtils {
- private static final int DATA_TYPE_FLAGS = 0x01;
- private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL = 0x02;
- private static final int DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE = 0x03;
- private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL = 0x04;
- private static final int DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE = 0x05;
- private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL = 0x06;
- private static final int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
- private static final int DATA_TYPE_LOCAL_NAME_SHORT = 0x08;
- private static final int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
- private static final int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
- private static final int DATA_TYPE_SERVICE_DATA_16_BIT = 0x16;
- private static final int DATA_TYPE_SERVICE_DATA_32_BIT = 0x20;
- private static final int DATA_TYPE_SERVICE_DATA_128_BIT = 0x21;
- private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
- private static final int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA_MOVE = 0xFE;
- private List<byte[]> mManufacturerByte;
- private byte[] mManufacturerByteMove;
- private List<ParcelUuid> mServiceUuids;
- private int mAdvertiseFlag = -1;
- private Map<ParcelUuid, byte[]> mServiceData;
- private String mDeviceName;
-
- public BleBroadcastUtils(byte[] scanRecord) {
- this(scanRecord, -1);
- }
-
- public BleBroadcastUtils(byte[] scanRecord, int manufacturerId) {
- mManufacturerByte=new ArrayList<>();
- getBleData(scanRecord, manufacturerId);
- }
-
- // Helper method to extract bytes from byte array.
- private static byte[] extractBytes(byte[] scanRecord, int start, int length) {
- byte[] bytes = new byte[length];
- System.arraycopy(scanRecord, start, bytes, 0, length);
- return bytes;
- }
-
-
- public List<byte[]> getManufacturerSpecificData() {
- return mManufacturerByte;
-
- }
-
- public byte[] getManufacturerByteMove() {
- return mManufacturerByteMove;
- }
-
- /**
- * 服务uuid
- *
- * @return {@link List}<{@link ParcelUuid}>
- */
- public List<ParcelUuid> getServiceUuids() {
- return mServiceUuids;
- }
-
- /**
- * 广告标志
- *
- * @return int
- */
- public int getAdvertiseFlag() {
- return mAdvertiseFlag;
- }
-
- public String getDeviceName() {
- return mDeviceName;
- }
-
- /**
- * 服务数据
- *
- * @return {@link Map}<{@link ParcelUuid}, {@link byte[]}>
- */
- public Map<ParcelUuid, byte[]> getServiceData() {
- return mServiceData;
- }
-
- /**
- * 服务数据
- *
- * @param serviceDataUuid 服务数据uuid
- * @return {@link byte[]}
- */
- public byte[] getServiceData(final ParcelUuid serviceDataUuid) {
- //noinspection ConstantConditions
- if (serviceDataUuid == null || mServiceData == null) {
- return null;
- }
- return mServiceData.get(serviceDataUuid);
- }
-
- private void getBleData(byte[] scanRecord, int id) {
- int currentPos = 0;
- mServiceUuids = new ArrayList<>();
- try {
- while (currentPos < scanRecord.length) {
- int length = scanRecord[currentPos++] & 0xFF;
- if (length == 0)
- break;
- int dataLength = length - 1;
- int fieldType = scanRecord[currentPos++] & 0xFF;
-
- switch (fieldType) {
- case DATA_TYPE_FLAGS:
- mAdvertiseFlag = scanRecord[currentPos] & 0xFF;
- break;
-
- case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:
- case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:
- parseServiceUuid(scanRecord, currentPos, dataLength, BluetoothUuid.UUID_BYTES_16_BIT, mServiceUuids);
- break;
- case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:
- case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:
- parseServiceUuid(scanRecord, currentPos, dataLength, BluetoothUuid.UUID_BYTES_32_BIT, mServiceUuids);
- break;
- case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:
- case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:
- parseServiceUuid(scanRecord, currentPos, dataLength, BluetoothUuid.UUID_BYTES_128_BIT, mServiceUuids);
- break;
- case DATA_TYPE_SERVICE_DATA_16_BIT:
- case DATA_TYPE_SERVICE_DATA_32_BIT:
- case DATA_TYPE_SERVICE_DATA_128_BIT:
- int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
- if (fieldType == DATA_TYPE_SERVICE_DATA_32_BIT) {
- serviceUuidLength = BluetoothUuid.UUID_BYTES_32_BIT;
- } else if (fieldType == DATA_TYPE_SERVICE_DATA_128_BIT) {
- serviceUuidLength = BluetoothUuid.UUID_BYTES_128_BIT;
- }
-
- final byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
- serviceUuidLength);
- final ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(
- serviceDataUuidBytes);
- final byte[] serviceDataArray = extractBytes(scanRecord,
- currentPos + serviceUuidLength, dataLength - serviceUuidLength);
- if (mServiceData == null)
- mServiceData = new HashMap<>();
- mServiceData.put(serviceDataUuid, serviceDataArray);
- break;
- case DATA_TYPE_LOCAL_NAME_SHORT:
- case DATA_TYPE_LOCAL_NAME_COMPLETE:
- mDeviceName = new String(extractBytes(scanRecord, currentPos, dataLength));
- break;
-
- case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
- if (id == -1) {
- byte[] bytes = extractBytes(scanRecord, currentPos, dataLength);
- mManufacturerByte.add(bytes);
- } else {
- int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) + (scanRecord[currentPos] & 0xFF);
- if (manufacturerId == id) {
- byte[] bytes = extractBytes(scanRecord, currentPos, dataLength);
- mManufacturerByte.add(bytes);
- } else {
- currentPos += dataLength;
- }
- }
- break;
- case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA_MOVE:
- mManufacturerByteMove = extractBytes(scanRecord, currentPos, dataLength);
- break;
-
- default:
- break;
- }
- currentPos += dataLength;
- }
- } catch (Exception e) {
- mServiceUuids = null;
- mManufacturerByte = null;
- e.printStackTrace();
- }
- if (mServiceUuids!=null&&mServiceUuids.isEmpty()) {
- mServiceUuids = null;
- }
- }
-
-
- // Parse service UUIDs.
- private static int parseServiceUuid(byte[] scanRecord, int currentPos, int dataLength, int uuidLength, List<ParcelUuid> serviceUuids) {
- while (dataLength > 0) {
- byte[] uuidBytes = extractBytes(scanRecord, currentPos, uuidLength);
- serviceUuids.add(BluetoothUuid.parseUuidFrom(uuidBytes));
- dataLength -= uuidLength;
- currentPos += uuidLength;
- }
- return currentPos;
- }
-
- }
|