时间:2021-12-24 11:07:19 | 栏目:Android代码 | 点击:次
IBeacon是BLE的一种,搜索iBeacon基站关键在于设备扫描到的scanRecord数组,识别是否有下面加粗斜体的02 15这两个数字。如果有,搜索到的蓝牙设备就是IBeacon。
// AirLocate:
// 02 01 1a 1a ff 4c 00 02 15 # Apple's fixed iBeacon advertising prefix
// e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile uuid
// 00 00 # major
// 00 00 # minor
// c5 # The 2's complement of the calibrated Tx Power
下面分步骤来实现检测IBeacon热点。
一、获得手机蓝牙控制权限
在manifest 文件中写上:
<uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
二、检测手机是否支持蓝牙,并获取mBluetoothAdapter 对象
if (!getPackageManager().hasSystemFeature( PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT) .show(); finish(); } final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = bluetoothManager.getAdapter(); if (mBluetoothAdapter == null) { Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); finish(); return; }
三、实现LeScanCallback回调接口
设备每次检测到一个蓝牙设备,就会回调这个接口中的onLeScan()方法,并且传入扫描到的device,rssi,scanRecord等参数。
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { //在这里处理扫描到的参数 //判断是不是IBeacon设备,做相应的处理。 } };
四、处理扫描到的参数的方法
public class iBeaconClass { static public class iBeacon { public String name; public int major; public int minor; public String proximityUuid; public String bluetoothAddress; public int txPower; public int rssi; } /** * 将扫描到的信息传入这个方法 * 该方法会判断扫描到的设备是不是IBeacon * 如果是就返回一个IBeacon对象 * 如果不是就返回null * @param device * @param rssi * @param scanData * @return */ public static iBeacon fromScanData(BluetoothDevice device, int rssi, byte[] scanData) { int startByte = 2; boolean patternFound = false; while (startByte <= 5) { if (((int) scanData[startByte + 2] & 0xff) == 0x02 && ((int) scanData[startByte + 3] & 0xff) == 0x15) { // yes! This is an iBeacon patternFound = true; break; } else if (((int) scanData[startByte] & 0xff) == 0x2d && ((int) scanData[startByte + 1] & 0xff) == 0x24 && ((int) scanData[startByte + 2] & 0xff) == 0xbf && ((int) scanData[startByte + 3] & 0xff) == 0x16) { iBeacon iBeacon = new iBeacon(); iBeacon.major = 0; iBeacon.minor = 0; iBeacon.proximityUuid = "00000000-0000-0000-0000-000000000000"; iBeacon.txPower = -55; return iBeacon; } else if (((int) scanData[startByte] & 0xff) == 0xad && ((int) scanData[startByte + 1] & 0xff) == 0x77 && ((int) scanData[startByte + 2] & 0xff) == 0x00 && ((int) scanData[startByte + 3] & 0xff) == 0xc6) { iBeacon iBeacon = new iBeacon(); iBeacon.major = 0; iBeacon.minor = 0; iBeacon.proximityUuid = "00000000-0000-0000-0000-000000000000"; iBeacon.txPower = -55; return iBeacon; } startByte++; } if (patternFound == false) { // This is not an iBeacon return null; } iBeacon iBeacon = new iBeacon(); iBeacon.major = (scanData[startByte + 20] & 0xff) * 0x100 + (scanData[startByte + 21] & 0xff); iBeacon.minor = (scanData[startByte + 22] & 0xff) * 0x100 + (scanData[startByte + 23] & 0xff); iBeacon.txPower = (int) scanData[startByte + 24]; // this one is signed iBeacon.rssi = rssi; // AirLocate: // 02 01 1a 1a ff 4c 00 02 15 # Apple's fixed iBeacon advertising prefix // e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile // uuid // 00 00 # major // 00 00 # minor // c5 # The 2's complement of the calibrated Tx Power // Estimote: // 02 01 1a 11 07 2d 24 bf 16 // 394b31ba3f486415ab376e5c0f09457374696d6f7465426561636f6e00000000000000000000000000000000000000000000000000 byte[] proximityUuidBytes = new byte[16]; System.arraycopy(scanData, startByte + 4, proximityUuidBytes, 0, 16); String hexString = bytesToHexString(proximityUuidBytes); StringBuilder sb = new StringBuilder(); sb.append(hexString.substring(0, 8)); sb.append("-"); sb.append(hexString.substring(8, 12)); sb.append("-"); sb.append(hexString.substring(12, 16)); sb.append("-"); sb.append(hexString.substring(16, 20)); sb.append("-"); sb.append(hexString.substring(20, 32)); iBeacon.proximityUuid = sb.toString(); if (device != null) { iBeacon.bluetoothAddress = device.getAddress(); iBeacon.name = device.getName(); } return iBeacon; } private static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(""); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } }
五、开启蓝牙
mBluetoothAdapter.enable();
六、开始扫描
mBluetoothAdapter.startLeScan(mLeScanCallback);
代码改自链接地址