Android检测IBeacon热点

本文介绍了如何在Android设备上检测IBeacon热点。关键在于解析scanRecord数组,寻找特定标识来确认是否为IBeacon。实现过程包括获取蓝牙权限、检查蓝牙支持、实现LeScanCallback回调、处理扫描参数、开启蓝牙以及启动扫描。参考了https://github.com/RadiusNetworks/android-ibeacon-service/和http://blog.youkuaiyun.com/hellogv/的相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);

代码改自https://github.com/RadiusNetworks/android-ibeacon-service/
参考博客:http://blog.youkuaiyun.com/hellogv/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值