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++;
}
}
}