Android 开发中 iBeacon的使用

一身转战三千里,一剑曾当百万师。这篇文章主要讲述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:只支持低功耗蓝牙设备
Android 开发中 iBeacon的使用

文章图片


 
【Android 开发中 iBeacon的使用】BLE与传统的蓝牙相比最大的优势是功耗降低90%,同时传输距离增大(超过100米)、安全和稳定性提高(支持AES加密和CRC验证)。iBeacon同时有一些自己的特点:
  • 无需配对,一般蓝牙设备印象中都需要配对工作。iBeacon无需配对,因为它是采用蓝牙的广播频道传送信号。
  • 程序可以后台唤醒,iBeacon的信息推送需要App支持。但是我们接收iBeacon信号无需打开App,只要保证安装了,同时手机蓝牙打开。
iBeacon是如何工作呢?实际上iBeacon基站通过蓝牙的广播频道不断向外发送位置信息,发送频率越快越耗电。也就是说iBeacon并不推送消息,而只是用于定位,推送消息的功能必须由App来完成。苹果定义了iBeacon 其中32位广播的数据格式。
Android 开发中 iBeacon的使用

文章图片


  • 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
  1. final  BluetoothManager  bluetoothManager  =   
  2.                                 (BluetoothManager)  getSystemService(Context.BLUETOOTH_SERVICE);    
  3.                 mBluetoothAdapter  =  bluetoothManager.getAdapter();    
  4.                 mBluetoothAdapter.startLeScan(mLeScanCallback);    

然后就是它的回调,在这里对搜索到的iBeacon设备距手机的信号强度做了一个排序
[java] view plain copy
  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.         };    
最后把搜索到的数据添加到集合中去
[java] view plain copy
  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
[java] view plain copy
    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.         }       




    推荐阅读