• Android 开发中 iBeacon的使用


    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:只支持低功耗蓝牙设备

    estimote-ibeacon-teardown2

    BLE与传统的蓝牙相比最大的优势是功耗降低90%,同时传输距离增大(超过100米)、安全和稳定性提高(支持AES加密和CRC验证)。iBeacon同时有一些自己的特点:

    • 无需配对,一般蓝牙设备印象中都需要配对工作。iBeacon无需配对,因为它是采用蓝牙的广播频道传送信号。
    • 程序可以后台唤醒,iBeacon的信息推送需要App支持。但是我们接收iBeacon信号无需打开App,只要保证安装了,同时手机蓝牙打开。

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

    estimote-ibeacon-teardown3

    • 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对象:

    1. final BluetoothManager bluetoothManager =  
    2.                 (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);  
    3.         mBluetoothAdapter = bluetoothManager.getAdapter();  
    4.         mBluetoothAdapter.startLeScan(mLeScanCallback);  


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

    1. private BluetoothAdapter.LeScanCallback mLeScanCallback =  
    2.             new BluetoothAdapter.LeScanCallback() {  
    3.   
    4.         @Override  
    5.         public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {  
    6.             final iBeacon ibeacon = iBeaconClass.fromScanData(device,rssi,scanRecord);  
    7.             addDevice(ibeacon);  
    8.             Collections.sort(mLeDevices, new Comparator<iBeacon>() {  
    9.                 @Override  
    10.                 public int compare(iBeacon h1, iBeacon h2) {  
    11.                     return h2.rssi - h1.rssi;  
    12.                 }  
    13.             });  
    14.         }  
    15.     };  

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

    1. private ArrayList<iBeacon> mLeDevices = new ArrayList<iBeacon>();  
    2.     private void addDevice(iBeacon device) { //更新beacon信息  
    3.         if(device==null) {  
    4.             Log.d("DeviceScanActivity ", "device==null ");  
    5.             return;  
    6.         }  
    7.           
    8.         for(int i=0;i<mLeDevices.size();i++){  
    9.             String btAddress = mLeDevices.get(i).bluetoothAddress;  
    10.             if(btAddress.equals(device.bluetoothAddress)){  
    11.                 mLeDevices.add(i+1, device);  
    12.                 mLeDevices.remove(i);  
    13.                 break;  
    14.             }   
    15.         }  
    16.         mLeDevices.add(device);  
    17.           
    18.     }  

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

      1. public class iBeaconClass {  
      2.   
      3.     static public  class iBeacon{  
      4.         public String name;  
      5.         public int major;  
      6.         public int minor;  
      7.         public String proximityUuid;  
      8.         public String bluetoothAddress;  
      9.         public int txPower;  
      10.         public int rssi;  
      11.     }  
      12.     public static iBeacon fromScanData(BluetoothDevice device, int rssi,byte[] scanData) {  
      13.   
      14.         int startByte = 2;  
      15.         boolean patternFound = false;  
      16.         while (startByte <= 5) {  
      17.             if (((int)scanData[startByte+2] & 0xff) == 0x02 &&  
      18.                 ((int)scanData[startByte+3] & 0xff) == 0x15) {            
      19.                 // yes!  This is an iBeacon   
      20.                 patternFound = true;  
      21.                 break;  
      22.             }  
      23.             else if (((int)scanData[startByte] & 0xff) == 0x2d &&  
      24.                     ((int)scanData[startByte+1] & 0xff) == 0x24 &&  
      25.                     ((int)scanData[startByte+2] & 0xff) == 0xbf &&  
      26.                     ((int)scanData[startByte+3] & 0xff) == 0x16) {  
      27.                 iBeacon iBeacon = new iBeacon();  
      28.                 iBeacon.major = 0;  
      29.                 iBeacon.minor = 0;  
      30.                 iBeacon.proximityUuid = "00000000-0000-0000-0000-000000000000";  
      31.                 iBeacon.txPower = -55;  
      32.                 return iBeacon;  
      33.             }  
      34.             else if (((int)scanData[startByte] & 0xff) == 0xad &&  
      35.                      ((int)scanData[startByte+1] & 0xff) == 0x77 &&  
      36.                      ((int)scanData[startByte+2] & 0xff) == 0x00 &&  
      37.                      ((int)scanData[startByte+3] & 0xff) == 0xc6) {  
      38.                      
      39.                     iBeacon iBeacon = new iBeacon();  
      40.                     iBeacon.major = 0;  
      41.                     iBeacon.minor = 0;  
      42.                     iBeacon.proximityUuid = "00000000-0000-0000-0000-000000000000";  
      43.                     iBeacon.txPower = -55;  
      44.                     return iBeacon;  
      45.             }  
      46.             startByte++;  
      47.         }  
      48.   
      49.   
      50.         if (patternFound == false) {  
      51.             // This is not an iBeacon  
      52.             return null;  
      53.         }  
      54.   
      55.         iBeacon iBeacon = new iBeacon();  
      56.   
      57.         iBeacon.major = (scanData[startByte+20] & 0xff) * 0x100 + (scanData[startByte+21] & 0xff);  
      58.         iBeacon.minor = (scanData[startByte+22] & 0xff) * 0x100 + (scanData[startByte+23] & 0xff);  
      59.         iBeacon.txPower = (int)scanData[startByte+24]; // this one is signed  
      60.         iBeacon.rssi = rssi;  
      61.   
      62.         // AirLocate:  
      63.         // 02 01 1a 1a ff 4c 00 02 15  # Apple's fixed iBeacon advertising prefix  
      64.         // e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile uuid  
      65.         // 00 00 # major   
      66.         // 00 00 # minor   
      67.         // c5 # The 2's complement of the calibrated Tx Power  
      68.   
      69.         // Estimote:          
      70.         // 02 01 1a 11 07 2d 24 bf 16   
      71.         // 394b31ba3f486415ab376e5c0f09457374696d6f7465426561636f6e00000000000000000000000000000000000000000000000000  
      72.   
      73.         byte[] proximityUuidBytes = new byte[16];  
      74.         System.arraycopy(scanData, startByte+4, proximityUuidBytes, 0, 16);   
      75.         String hexString = bytesToHexString(proximityUuidBytes);  
      76.         StringBuilder sb = new StringBuilder();  
      77.         sb.append(hexString.substring(0,8));  
      78.         sb.append("-");  
      79.         sb.append(hexString.substring(8,12));  
      80.         sb.append("-");  
      81.         sb.append(hexString.substring(12,16));  
      82.         sb.append("-");  
      83.         sb.append(hexString.substring(16,20));  
      84.         sb.append("-");  
      85.         sb.append(hexString.substring(20,32));  
      86.         iBeacon.proximityUuid = sb.toString();  
      87.   
      88.         if (device != null) {  
      89.             iBeacon.bluetoothAddress = device.getAddress();  
      90.             iBeacon.name = device.getName();  
      91.         }  
      92.   
      93.         return iBeacon;  
      94.     }  
      95.   
      96.     public static String bytesToHexString(byte[] src){    
      97.         StringBuilder stringBuilder = new StringBuilder("");    
      98.         if (src == null || src.length <= 0) {    
      99.             return null;    
      100.         }    
      101.         for (int i = 0; i < src.length; i++) {    
      102.             int v = src[i] & 0xFF;    
      103.             String hv = Integer.toHexString(v);    
      104.             if (hv.length() < 2) {    
      105.                 stringBuilder.append(0);    
      106.             }    
      107.             stringBuilder.append(hv);    
      108.         }    
      109.         return stringBuilder.toString();    
      110.     }    
  • 相关阅读:
    elementUI 表格分页后台排序记录
    oracle乱码记录
    JavaScript 数字转汉字+element时间选择器快速选择
    js中call()方法和apply方法的使用
    Rails导出CSV
    CakePHP2.x 发送邮件
    一个例子说明substr(), mb_substr() 和 mb_strcut()之间的区别
    substr是不安全的
    CakePHP中回调函数的使用
    cakephp中find('list')的使用
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6098767.html
Copyright © 2020-2023  润新知