Android iBeacon 开发

iBeacon是苹果公司称为“一种可以检测到附近IOS7设备出现的一种新的低功耗、低成本信号传送器”的一套室内定位系统的商标。 这种技术可以使一个智能手机或其他装置在一个iBeacon基站的感应范围内能够执行相应的命令。iBeacon通过低功耗蓝牙近距离感应来向一个app或操作系统传输通用唯一识别码。


关于iBeacon的工作原理,请参考

http://blog.csdn.net/qinxiandiqi/article/details/39004337


iBeacon毕竟是苹果的东西,所以苹果提供了一套完整的iBeacon API给IOS开发人员,开发人员轻轻松松就可以让自己的APP实现相关功能。

相对来说,Android开发人员就比较麻烦了,需要自己调用BluetoothAdapter.startLeScan()去搜索iBeacon商标,

搜索出结果之后,还需要自己去解析iBeacon Format,多麻烦……


最近在GitHub上找到了一个开源库Android-Beacon-Library,它封装了一系列Beacons API(风格类似IOS),

Android开发人员,很轻松就可以将它整合到自己的APP中。



android-beacon-library官方网站:

http://altbeacon.github.io/android-beacon-library


网站里面有示例、代码、入门 、问题提交等,大家可以去看看……


注意,本人运行官方的示例,无法正常使用。主要原因是需要重新设置BeaconParser。

下面是我写的一个例子,供大家参考:


[java]  view plain  copy
  1. package com.example.sample_beacon;  
  2.   
  3. import java.util.Collection;  
  4.   
  5. import org.altbeacon.beacon.Beacon;  
  6. import org.altbeacon.beacon.BeaconConsumer;  
  7. import org.altbeacon.beacon.BeaconManager;  
  8. import org.altbeacon.beacon.BeaconParser;  
  9. import org.altbeacon.beacon.MonitorNotifier;  
  10. import org.altbeacon.beacon.RangeNotifier;  
  11. import org.altbeacon.beacon.Region;  
  12.   
  13. import android.app.Activity;  
  14. import android.os.Bundle;  
  15. import android.os.RemoteException;  
  16. import android.util.Log;  
  17.   
  18. public class MainActivity extends Activity implements BeaconConsumer  
  19. {  
  20.     protected static final String TAG = "MonitoringActivity";  
  21.     /** 重新调整格式*/  
  22.     public static final String IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";  
  23.     /** 设置兴趣UUID*/  
  24.     public static final String FILTER_UUID = "E2C56DB5-DFFB-48D2-B060-D0F5A71096E0";  
  25.       
  26.     private BeaconManager beaconManager;  
  27.   
  28.     @Override  
  29.     protected void onCreate(Bundle savedInstanceState)  
  30.     {  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.activity_main);  
  33.   
  34.         beaconManager = BeaconManager.getInstanceForApplication(this);  
  35.         beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON_FORMAT));  
  36.         beaconManager.bind(this);  
  37.     }  
  38.   
  39.     @Override  
  40.     protected void onDestroy()  
  41.     {  
  42.         super.onDestroy();  
  43.         beaconManager.unbind(this);  
  44.     }  
  45.   
  46.     @Override  
  47.     public void onBeaconServiceConnect()  
  48.     {  
  49.         beaconManager.setMonitorNotifier(new MonitorNotifier()  
  50.         {  
  51.             @Override  
  52.             public void didEnterRegion(Region region)  
  53.             {  
  54.                 Log.e(TAG, "I just saw an beacon for the first time!");  
  55.             }  
  56.   
  57.             @Override  
  58.             public void didExitRegion(Region region)  
  59.             {  
  60.                 Log.e(TAG, "I no longer see an beacon");  
  61.             }  
  62.   
  63.             @Override  
  64.             public void didDetermineStateForRegion(int state, Region region)  
  65.             {  
  66.                 Log.e(TAG, "I have just switched from seeing/not seeing beacons: " + state);  
  67.             }  
  68.         });  
  69.   
  70.         try  
  71.         {  
  72.             //开始监视  
  73.             beaconManager.startMonitoringBeaconsInRegion(new Region(FILTER_UUID, nullnullnull));  
  74.         }  
  75.         catch (RemoteException e)  
  76.         {  
  77.             e.printStackTrace();  
  78.         }  
  79.     }  
  80.   
  81. }  

上述示例中,通过调用 beaconManager.getBeaconParsers()获取到BeaconParser列表,然后往里面添加一个我们自己定义的BeaconParser。

而BeaconParser是通过setBeaconLayout(String)方法,设置对应的Beacon格式。


以下是设置的iBeacon格式

[java]  view plain  copy
  1. IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";  

  •    m - matching byte sequence for this beacon type to parse (exactly one required)
       s - ServiceUuuid for this beacon type to parse (optional, only for Gatt-based becons)
       i - identifier (at least one required, multiple allowed)
       p - power calibration field (exactly one required)
       d - data field (optional, multiple allowed)


下面来简单说一下iBeacon广播的数据。


一般来说,我们在调用BluetoothAdapter.startLeScan()搜索iBeacon的时候,

会在回调函数onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord)中获取到iBeacon发出广播数据,

就是参数scanRecord所携带的数据。如下所示:

[java]  view plain  copy
  1. 02 01 06 1A FF 4C 00 02 15 E2 C5 6D B5 DF FB 48 D2 B0 60 D0 F5 A7 10 96 E0 00 03 00 03 CD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   

把其它无关数据去掉,变成

[java]  view plain  copy
  1. 02 01 06 1A FF 4C 00 02 15 E2 C5 6D B5 DF FB 48 D2 B0 60 D0 F5 A7 10 96 E0 00 03 00 03 CD  

以上数据只包含了实际信息数据(其它数据如MAC、数据包报头……不在这里),共30字节

经过整理后,变成

[plain]  view plain  copy
  1. 02 01 06 1A FF 4C 00 02 15  (iBeacon的前缀,固定不变的)  
  2. E2 C5 6D B5 DF FB 48 D2 B0 60 D0 F5 A7 10 96 E0 (UUID的值)  
  3. 00 03 (major值)  
  4. 00 03 (minor值)  
  5. CD (tx值,表示距离1米是应该接收到的信号强度,可用于计算距离)  

按照相关资料所述,识别是否iBeacon靠上面的红字(0215),参考资料如下

https://github.com/RadiusNetworks/android-ibeacon-service/blob/master/src/main/java/com/radiusnetworks/ibeacon/IBeacon.java



再回到之前我们要设置的BeaconParser的问题上……

在默认情况下,通过beaconManager.getBeaconParsers()方法获取到BeaconParser列表,默认只有一个。

而且,该默认的BeaconParser被设置为"m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25",

注意看m值,这里是”beac“来的,并不是iBeacon的标识,

也就是说,android-beacon-library这个库默认情况下,并不是用于扫描iBeacon,

想要用于扫描iBeacon商标,需要做以上修改 ……



好了,有点绕……没办法……



下面是我写的示例,仅供参考

http://download.csdn.net/detail/eieihihi/8679825

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值