Android 蓝牙(4.0)BLE开发 扫描IBeacon

一.扫描蓝牙设备

1.  在程序manifest文件中添加声明蓝牙权限的代码。

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

如果想让程序只能在支持BLE设备上运行的,可将下面的代码添加到manifest文件中去:

<uses-featue android:name=”android.hardwoare.bletooth_le”android:required=”ture”/>

2.  获取运行时权限

int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if (permission == PackageManager.PERMISSION_GRANTED) {
//执行开始扫描
}else {
    //申请权限
    ActivityCompat.requestPermissions(this, new String[] 
{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, 1});
}

3.  扫描蓝牙

扫描蓝呀设备主要用到BluetoothManager和BluetoothAdapter两个类。首先获取蓝牙服务,然后获通过蓝牙服务获取蓝牙适配器,最后在通过蓝牙适配器来开启蓝牙扫描。扫描到蓝牙设备后就调用回调接口,回掉接口有两种分别是LeScanCallback和ScanCallback; 其中LeScanCallback现在已经废弃(仍然能使用)

代码:

//获取蓝牙adapter
BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
第一种扫描:
bluetoothAdapter.startLeScan(callback); // 开始扫描
bluetoothAdapter.stopLeScan(callback);  // 停止扫描

蓝牙扫描回调

private BluetoothAdapter.LeScanCallback callback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            /**
             * device:BluetoothDevice类对象,通过该对象可以得到MAC地址、设备名称等信息
             * rssi:蓝牙设备场强值
             * scanRecord - 这里内容比较丰富,像UUID、Major、Minor都在这里
             */           
            IBeaconRecord record = new IBeaconRecord();
            if (fromScanData(scanRecord, record)) {
                String address = device.getAddress();   // 获取Mac地址
                String name = device.getName();         // 获取设备名称

                record.address = address;   // Mac地址
                record.rssi = rssi;     // 场强
                if (mapBltScanResult.containsKey(key)) {
                    mapBltScanResult.get(key).add(record);
                } else {
                    ArrayList<IBeaconRecord> list = new ArrayList<>();
                    list.add(record);
                    mapBltScanResult.put(key, list);
                }
            }
        }
    };

    /**
     * 解析蓝牙信息数据流 (此段代码来源于网络)
     * @param 设备蓝牙扫描到的字节数组
     * @param record 用来保存解析出来的蓝牙数据
     * @return Boolean
     */
    private boolean fromScanData(byte[] scanData, IBeaconRecord record) {

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

                return false;
            } 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) {

                return false;
            }
            startByte++;
        }

        if (patternFound == false) {
            // This is not an iBeacon
            return false;
        }

        // 获得Major属性
        record.major = (scanData[startByte + 20] & 0xff) * 0x100
                + (scanData[startByte + 21] & 0xff);

        record.txPower = (int)scanData[startByte+24];

        // 获得Minor属性
        record.minor = (scanData[startByte + 22] & 0xff) * 0x100
                + (scanData[startByte + 23] & 0xff);

        // record.tx_power = (int) scanData[startByte + 24]; // this one is

        try {
            byte[] proximityUuidBytes = new byte[16];
            System.arraycopy(scanData, startByte + 4, proximityUuidBytes, 0, 16);
            String hexString = bytesToHex(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));
            // beacon.put("proximity_uuid", sb.toString());
            // 获得UUID属性
            record.uuid = sb.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    private char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
            '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    private String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        int v;
        for (int j = 0; j < bytes.length; j++) {
            v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

第二种扫描:

由于此方式仅支持Android 5.0以上的系统,所以在使用时需判断当前系统版本

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mBluetoothAdapter.getBluetoothLeScanner().startScan(callback); // 开始扫描
            mBluetoothAdapter.getBluetoothLeScanner().stopScan(callback);  // 停止扫描
        }
ScanCallback callback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            result.getRssi();                // 场强
            result.getTxPower();             // 距离设备1米的时候的信号强度
            result.getDevice().getAddress(); // 设备MAC地址
            result.getDevice().getName();    // 设备名
        }


        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
        }


        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
        }
    };











  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值