«

【Android开发】关于android-beacon-library

时间:2024-3-2 17:35     作者:韩俊     分类: Android


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。

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


package com.example.sample_beacon;

import java.util.Collection;

import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.MonitorNotifier;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;

import android.app.Activity;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;

public class MainActivity extends Activity implements BeaconConsumer
{
    protected static final String TAG = "MonitoringActivity";
    /** 重新调整格式*/
    public static final String IBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24";
    /** 设置兴趣UUID*/
    public static final String FILTER_UUID = "E2C56DB5-DFFB-48D2-B060-D0F5A71096E0";

    private BeaconManager beaconManager;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        beaconManager = BeaconManager.getInstanceForApplication(this);
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON_FORMAT));
        beaconManager.bind(this);
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        beaconManager.unbind(this);
    }

    @Override
    public void onBeaconServiceConnect()
    {
        beaconManager.setMonitorNotifier(new MonitorNotifier()
        {
            @Override
            public void didEnterRegion(Region region)
            {
                Log.e(TAG, "I just saw an beacon for the first time!");
            }

            @Override
            public void didExitRegion(Region region)
            {
                Log.e(TAG, "I no longer see an beacon");
            }

            @Override
            public void didDetermineStateForRegion(int state, Region region)
            {
                Log.e(TAG, "I have just switched from seeing/not seeing beacons: " + state);
            }
        });

        try
        {
            //开始监视
            beaconManager.startMonitoringBeaconsInRegion(new Region(FILTER_UUID, null, null, null));
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
    }

}

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

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


以下是设置的iBeacon格式

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所携带的数据。如下所示:

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 

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

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字节

经过整理后,变成

02 01 06 1A FF 4C 00 02 15  (iBeacon的前缀,固定不变的)
E2 C5 6D B5 DF FB 48 D2 B0 60 D0 F5 A7 10 96 E0 (UUID的值)
00 03 (major值)
00 03 (minor值)
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






标签: android

热门推荐