IBeacon開發之旅《一》掃描iBeacon信號
由於公司最近項目與iBeancon有關,關於室內定位的開發,有關Ibeancon的原理介紹,大家自行百度。
首先我們需要引入一個依賴 :
compile 'org.altbeacon:android-beacon-library:2.13.1'
注意:在6.0設備上需要對權限進行動態申請,需要的權限如下
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-feature android:name="android.hardware.bluetooth_le"android:required="true"/>
- 先看效果
- 初始化service
我們採用的方式是通過後臺服務,一秒掃描一次,然後通過廣播發送給view
public class BeaconService extends Service implements BeaconConsumer, RangeNotifier {
private static final long DEFAULT_BACKGROUND_SCAN_PERIOD = 2000L;
private static final long DEFAULT_BACKGROUND_BETWEEN_SCAN_PERIOD = 2000L;
private BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
public BeaconService() {
}
@Override
public void onCreate() {
super.onCreate();
initBeacon();
beaconManager.bind(this);
}
private void initBeacon() {
beaconManager.setBackgroundScanPeriod(DEFAULT_BACKGROUND_SCAN_PERIOD);
beaconManager.setBackgroundScanPeriod(DEFAULT_BACKGROUND_BETWEEN_SCAN_PERIOD);
}
@Override
public void onDestroy() {
super.onDestroy();
if (beaconManager != null)
beaconManager.removeRangeNotifier(this);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onBeaconServiceConnect() {
Region region = new Region("myRangingUniqueId", null, null, null);
beaconManager.addRangeNotifier(this);
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> collections, Region region) {
List<Beacon> beacons = new ArrayList<>();
for (Beacon beacon : collections) {
beacons.add(beacon);
}
Intent intent = new Intent(MainActivity.BEACON_ACTION);
intent.putParcelableArrayListExtra("beacon", (ArrayList<? extends Parcelable>) beacons);//因爲Beacon繼承了Parcelable,
sendBroadcast(intent); // 所以能通過這個方式來傳遞數據
}
}
- 我們在activity中啓動service,然後創建廣播接受者,接收數據,由於每次接收的數據條目不一致,所以需要對數據進行處理,原理就是,有新數據更新新數據,沒有新數據,保留舊數據,最後將數據進行排序操作,這裏要自定義排序方法,按照距離進行排序,Collections.sort();
class BeaconBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BEACON_ACTION.equals(action)) {
ArrayList<Beacon> allDevice = intent.getParcelableArrayListExtra("beacon");
//遍歷新的設備
for (Beacon beacon : allDevice) {
/**
* 如果有新設備,則將舊設備移除 將新設備添加
* 如果沒有直接添加
* 一秒刷新一次 更加直觀
* */
addDevice(beacon);
}
//對拿到的結果進行排序操作,自定義排序方法,按照距離排序
Collections.sort(beacons, new SortByDistance());
if (beacons != null) {
scanCount.setTitle("設備數:" + beacons.size());
if (lvDevice.getAdapter() == null) {
lvDevice.setAdapter(deviceAdapter);
} else {
deviceAdapter.notifyDataSetChanged();
}
}
count++;
}
}
}