iBeacon是苹果公司2013年9月发布的移动设备用OS(ios7)上配备的新功能。其主要的工作方式就是:配备有低功耗蓝牙
(BLE)通信功能的设备使用BLE技术向周围发送自己特有的ID。
这个网址对iBeacon进行了基本介绍,建议大家去阅读一下:http://www.beaconsandwich.com/what-is-ibeacon.html
在2015年,谷歌发布Eddystone,它其实类似于iBeacon。
对于这两者的主要区别,大家可以浏览这个网址的内容:https://www.zhihu.com/question/32708729
本文的demo开发是基于github上的一个开源项目Altbeacon:https://github.com/AltBeacon/android-beacon-library
Aitebeacon官方网站:http://altbeacon.github.io/android-beacon-library/
本文参照了:http://blog.csdn.net/wjskeepmaking/article/details/52067585
本文代码已上传至CSDN:http://download.csdn.net/download/eueheuen/10212291
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
//noinspection GradleDynamicVersion
implementation 'org.altbeacon:android-beacon-library:2+'
}
public class MyApp extends Application implements BootstrapNotifier {
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
@Override
public void onCreate() {
super.onCreate();
BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser()
.setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
Region region = new Region("all-region-beacon",null,null,null);
regionBootstrap = new RegionBootstrap(this,region);
backgroundPowerSaver = new BackgroundPowerSaver(this);
}
@Override
public void didEnterRegion(Region region) {
}
@Override
public void didExitRegion(Region region) {
}
@Override
public void didDetermineStateForRegion(int i, Region region) {
}
}
android:name="android.permission.BLUETOOTH"/>
android:name="android.permission.BLUETOOTH_ADMIN"/>
android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
android:name="android.permission.INTERNET"/>
android:name="android.permission.ACCESS_COARSE_LOCATION" />
android:name="android.permission.ACCESS_FINE_LOCATION" />
public class BeaconService extends Service implements BeaconConsumer, RangeNotifier {
//单位:毫秒
//后台扫描
private static final long DEFAULT_BACKGROUND_SCAN_PERIOD = 1000L;
private static final long DEFAULT_BACKGROUND_BETWEEN_SCAN_PERIOD = 0L;
//前台扫描
private static final long DEFAULT_SCAN_PERIOD = 1000L;
private static final long DEFAULT_BETWEEN_SCAN_PERIOD = 500L;
private BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
private MyBR myBR;
public BeaconService() {
}
@Override
public void onCreate() {
super.onCreate();
initBeacon();
beaconManager.bind(this);
myBR = new MyBR();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("");
registerReceiver(myBR,intentFilter);
}
private void initBeacon() {
//设置前台扫描时长
beaconManager.setForegroundScanPeriod(DEFAULT_SCAN_PERIOD);
//设置前台扫描间隔
beaconManager.setForegroundBetweenScanPeriod(DEFAULT_BETWEEN_SCAN_PERIOD);
//设置每个蓝牙LE扫描周期的持续时间(以毫秒为单位)以查找信标。
// 此函数用于设置调用bind(org.altbeacon.beacon.BeaconConsumer)之前的时间段或在背景/前景之间切换的时间段。
// 要使其在已经运行的扫描(在下一个周期开始时)生效,请调用updateScanPeriods()
//设置后台扫描时长
beaconManager.setBackgroundScanPeriod(DEFAULT_BACKGROUND_SCAN_PERIOD);
//当没有测距/监控客户端位于前台时,设置每个蓝牙LE扫描周期之间不扫描的时间(以毫秒为单位)
//设置后台扫描间隔
beaconManager.setBackgroundBetweenScanPeriod(DEFAULT_BACKGROUND_BETWEEN_SCAN_PERIOD);
}
@Override
public void onDestroy() {
super.onDestroy();
if (beaconManager != null){
beaconManager.removeRangeNotifier(this);
}
if (myBR!= null){
unregisterReceiver(myBR);
Toast.makeText(this,"完犊子了",Toast.LENGTH_SHORT).show();
Log.d("MyBeaconNum","完犊子了");
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onBeaconServiceConnect() {
Region region = new Region("all-region-beacon", null, null, null);
beaconManager.addRangeNotifier(this);
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void didRangeBeaconsInRegion(Collection collection, Region region) {
List beacons = new ArrayList<>();
for (Beacon beacon : collection) {
beacons.add(beacon);
}
Log.d("MyBeaconNum",beacons.size()+"");
Intent intent = new Intent(MainActivity.BEACON_ACTION);
intent.putParcelableArrayListExtra("beacon", (ArrayList extends Parcelable>) beacons);//因为Beacon继承了Parcelable,
sendBroadcast(intent);
}
class MyBR extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
stopSelf();
}
}
}
android:name=".BeaconService"
android:enabled="true"
android:exported="true"
tools:replace="android:exported"
android:isolatedProcess="false"
android:label="beacon" >
public class MainActivity extends AppCompatActivity {
private BeaconBroadcastReceiver beaconBroadcastReceiver;
private static final String TAG = "MyTAG";
public static final String BEACON_ACTION = "com.example.lenovo.mybeaconlib";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconBroadcastReceiver = new BeaconBroadcastReceiver();
Intent intent = new Intent(MainActivity.this, BeaconService.class);
startService(intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
//停止服务
Intent intent=new Intent("PleaseStopService");
sendBroadcast(intent);
if (beaconBroadcastReceiver != null){
try{
unregisterReceiver(beaconBroadcastReceiver);
}catch (Throwable ignored){
}
}
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(beaconBroadcastReceiver, getBeaconIntentFilter());
}
@Override
protected void onPause() {
super.onPause();
if (beaconBroadcastReceiver != null){
unregisterReceiver(beaconBroadcastReceiver);
}
}
class BeaconBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BEACON_ACTION.equals(action)) {
List beacons = intent.getParcelableArrayListExtra("beacon");
Log.i(TAG, "onReceive: "+ beacons.size());
for (Beacon beacon : beacons){
//获取 uuid,major,minor
String uuid = String.valueOf(beacon.getId1());
String major = String.valueOf(beacon.getId2());
String mMinor = String.valueOf(beacon.getId3());
int minor = Integer.parseInt(mMinor);
String text = "uuid: " + beacon.getServiceUuid() + "\r\n" +
"dis: " + beacon.getDistance() + "m" + "\r\n" +
"BluetoothName: " + beacon.getBluetoothName() + "\r\n" +
"BluetoothAddress: " + beacon.getBluetoothAddress() + "\r\n" +
"ParserIdentifier(分析器标识符): " + beacon.getParserIdentifier() + "\r\n" +
"BeaconTypeCode: " + beacon.getBeaconTypeCode() + "\r\n" +
"Rssi: " + beacon.getRssi() + "\r\n" +
"RunningAverageRssi:"+beacon.getRunningAverageRssi() + "\r\n" +
"TxPower: " + beacon.getTxPower() + "\r\n" +
"ExtraDataFields:"+beacon.getExtraDataFields() +"\r\n" +
"DataFields:"+beacon.getDataFields()+"\r\n" +
"BeaconToString:"+beacon.toString();
Log.i(TAG, "onReceive: "+ text);
}
Log.i(TAG, "onReceive: "+ "**********************************");
}
}
}
IntentFilter getBeaconIntentFilter() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BEACON_ACTION);
return intentFilter;
}
}