Android Beacon 開發(IBeacon)
阿新 • • 發佈:2019-01-04
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:
Aitebeacon官方網站:http://altbeacon.github.io/android-beacon-library/
本文參照了:http://blog.csdn.net/wjskeepmaking/article/details/52067585
本文程式碼已上傳至CSDN:http://download.csdn.net/download/eueheuen/10212291
1,建立工程之後,在buid.gradle中匯入AltBeacon Library:
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+'
}
2,建立一個Application,這個Application需要實現一個介面:BootstrapNotifier:
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) {
}
}
3,新增相關許可權:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
4,建立Service:
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<Beacon> collection, Region region) {
List<Beacon> 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();
}
}
}
5,不要忘記在Manifest中註冊Service:
<service
android:name=".BeaconService"
android:enabled="true"
android:exported="true"
tools:replace="android:exported"
android:isolatedProcess="false"
android:label="beacon" >
</service>
6,MainActivity:
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<Beacon> 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;
}
}