您的位置:首页 > 移动开发 > Android开发

Android 开发中 iBeacon的使用

2016-07-14 20:46 555 查看
转自:http://blog.csdn.net/jie1991liu/article/details/47403455

iBeacon的工作原理是基于Bluetooth Low Energy(BLE)低功耗蓝牙传输技术,iBeacon基站不断向四周发送蓝牙信号,当智能设备进入设定区域时,就能够收到信号。只要满足iBeacon技术标准的都可以使用,所以Android也能够支持iBeacon。Google在Android4.3中支持BLE技术

定位一直是非常关键的功能。通过iBeacon基站的部署能够实现室内导航,同时通过蓝牙推送信息,iBeacon在商场零售或者一些公共服务领域如体育馆、博物馆能提供非常棒的体验。尤其是蓝牙不错传输距离、低功耗、以及信号加密使得iBeacon在移动支付领域也非常有前景。总之,iBeacon的潜力似乎是无穷大,也受到了越来越多的关注。

要了解iBeacon是如何工作首先我们要了解BLE。BLE(也称为Bluetooth Smart)最早追溯到Nokia于2006年提出的Wibree,后来融合进了蓝牙标准,成为Bluetooth4.0的一部分。目前我们经常能看到3种蓝牙设备:
Bluetooth:只支持传统模式的蓝牙设备
Bluetooth Smart Ready:支持传统和低功耗两种模式设备
Bluetooth Smart:只支持低功耗蓝牙设备




BLE与传统的蓝牙相比最大的优势是功耗降低90%,同时传输距离增大(超过100米)、安全和稳定性提高(支持AES加密和CRC验证)。iBeacon同时有一些自己的特点:
无需配对,一般蓝牙设备印象中都需要配对工作。iBeacon无需配对,因为它是采用蓝牙的广播频道传送信号。
程序可以后台唤醒,iBeacon的信息推送需要App支持。但是我们接收iBeacon信号无需打开App,只要保证安装了,同时手机蓝牙打开。

iBeacon是如何工作呢?实际上iBeacon基站通过蓝牙的广播频道不断向外发送位置信息,发送频率越快越耗电。也就是说iBeacon并不推送消息,而只是用于定位,推送消息的功能必须由App来完成。苹果定义了iBeacon 其中32位广播的数据格式。



UUID:厂商识别号


Major:相当于群组号,同一个组里Beacon有相同的Major
Minor:相当于识别群组里单个的Beacon
TX Power:用于测量设备离Beacon的距离

UUID+Major+Minor就构成了一个Beacon的识别号,有点类似于网络中的IP地址。TX Power用于测距,iBeacon目前只定义了大概的3个粗略级别:
非常近(Immediate): 大概10厘米内
近(Near):1米内
远(Far):1米外

这里主要是对其用法做一个介绍:

首先是获取BluetoothAdapter对象:

[java] view
plain copy

final BluetoothManager bluetoothManager =  

                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);  

        mBluetoothAdapter = bluetoothManager.getAdapter();  

        mBluetoothAdapter.startLeScan(mLeScanCallback);  


然后就是它的回调,在这里对搜索到的iBeacon设备距手机的信号强度做了一个排序

[java] view
plain copy

private BluetoothAdapter.LeScanCallback mLeScanCallback =  

            new BluetoothAdapter.LeScanCallback() {  

  

        @Override  

        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {  

            final iBeacon ibeacon = iBeaconClass.fromScanData(device,rssi,scanRecord);  

            addDevice(ibeacon);  

            Collections.sort(mLeDevices, new Comparator<iBeacon>() {  

                @Override  

                public int compare(iBeacon h1, iBeacon h2) {  

                    return h2.rssi - h1.rssi;  

                }  

            });  

        }  

    };  

最后把搜索到的数据添加到集合中去

[java] view
plain copy

private ArrayList<iBeacon> mLeDevices = new ArrayList<iBeacon>();  

    private void addDevice(iBeacon device) { //更新beacon信息  

        if(device==null) {  

            Log.d("DeviceScanActivity ", "device==null ");  

            return;  

        }  

          

        for(int i=0;i<mLeDevices.size();i++){  

            String btAddress = mLeDevices.get(i).bluetoothAddress;  

            if(btAddress.equals(device.bluetoothAddress)){  

                mLeDevices.add(i+1, device);  

                mLeDevices.remove(i);  

                break;  

            }   

        }  

        mLeDevices.add(device);  

          

    }  



我们在iBbeaconClass类中对其进行数据的解析处理,参考:https://github.com/AltBeacon/android-beacon-library

[java] view
plain copy

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;  

    }  

    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;  

    }  

  

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

    }    

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: