1、初始化蓝牙管理类
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
2、初始化蓝牙适配器
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
3、开始扫描Beacon设备
private void scanLeDevice() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
bluetoothAdapter.stopLeScan(mLeScanCallback);
Toast.makeText(context,"停止扫描......",Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
mScanning = true;
mLeDeviceListAdapter.clear();
bluetoothAdapter.startLeScan(mLeScanCallback);
Toast.makeText(context,"开始扫描......",Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
}
4、扫描接口回调
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
final iBeaconClass.iBeacon ibeacon = iBeaconClass.fromScanData(device, rssi, scanRecord);
if (Looper.myLooper() == Looper.getMainLooper()) {
// Android 5.0 及以上
mLeDeviceListAdapter.updateList(ibeacon);
} else {
// Android 5.0 以下
runOnUiThread(new Runnable() {
@Override
public void run() {
mLeDeviceListAdapter.updateList(ibeacon);
}
});
}
}
};
5、iBeaconClass
public class iBeaconClass {
static public class iBeacon implements Serializable{
public String name;
public int major;
public int minor;
public String proximityUuid;
public String bluetoothAddress;
public int txPower;
public int rssi;
}
public static iBeacon fromScanData(BluetoothDevice device, int rssi, byte[] scanData) {
int startByte = 2;
boolean patternFound = false;
// 寻找ibeacon
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;
// 转换为16进制
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;
}
public 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();
}
protected static double calculateAccuracy(int txPower, double rssi) {
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
double ratio = rssi * 1.0 / txPower;
if (ratio < 1.0) {
return Math.pow(ratio, 10);
} else {
double accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
return accuracy;
}
}
}
注意:需要添加的权限
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />