【Android開發】關於android-beacon-library

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





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章