/** * 设置距离计算模型 * * @param distanceModelUpdateUrl null 使用asserts/model-distance-calculations.json; * 否则使用url指定的网上模型文件,如"http://data.altbeacon.org/android-distance.json" */ public void setDefaultDistanceCalcuator(String distanceModelUpdateUrl) { /** * 读取应用程序asserts/model-distance-calculations.json,在应用程序私有数据空间写入同名文件。 * java/org/altbeacon/beacon/distance/ModelSpecificDistanceCalculator.java的loadModelMapFromFile()读取此文件,以构造缺省模型。 */ if (distanceModelUpdateUrl == null) { try { String jsonString = stringFromAssertFile(); // 读取asserts/model-distance-calculations.json boolean ok = saveJson(jsonString); // 将距离模型json数据写入应用程序私有空间中的文件:CONFIG_FILE。 if (ok) { LogManager.d(TAG, "setDefaultDistanceCalcuator ok,from asserts/" + CONFIG_FILE); } else { LogManager.d(TAG, "setDefaultDistanceCalcuator error,from asserts/" + CONFIG_FILE); } } catch (IOException e) { LogManager.d(TAG, "Exception:" + e.toString()); } // 设置一个虚假的url,目的是引起BeaconService中调用ModelSpecificDistanceCalculator()-->loadModelMap()-->在应程序私有空间找CONFIG_FILE // 由于以上已经存储了这个文件,因此,绑定BeaconService后,执行上述序列,loadModelMap()能够成功找到该文件。 // 鉴于此,必须在绑定BeaconService前执行此函数。loadModelMap()仅在第一次调用时才检查此文件,一旦文件已经写入,下一次就不检查了。因此测试时,每次要完全卸载程序,才能验证此程序的逻辑。 BeaconManager.setDistanceModelUpdateUrl("nodistanceModelUpdateUrl"); } else { // BeaconService中调用ModelSpecificDistanceCalculator()设置距离计算模型 BeaconManager.setDistanceModelUpdateUrl(distanceModelUpdateUrl); LogManager.d(TAG, "setDefaultDistanceCalcuator, from " + distanceModelUpdateUrl); } }
/** * Sets the duration in milliseconds spent not scanning between each Bluetooth LE scan cycle when * no ranging/monitoring clients are in the background. default 5 minutes * * @param p (ms) */ public void setBackgroundBetweenScanPeriod(long p) { mBeaconManager.setBackgroundBetweenScanPeriod(p); try { mBeaconManager.updateScanPeriods(); // 保证在下一个循环扫描周期生效 } catch (RemoteException e) { LogManager.d(TAG, "RemoteException:" + e.toString()); } }
public WMBeaconManager( MonitorNotifier monitorNotifier, RangeNotifier rangeNotifier, Context context) { this.context = context; mBeaconManager = BeaconManager.getInstanceForApplication(this.context); // Detect the main Eddystone-UID frame: mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(EDDYSTONE_LAYOUT)); mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(IBEACON_LAYOUT)); mBeaconManager.setRangeNotifier(rangeNotifier); mBeaconManager.setMonitorNotifier(monitorNotifier); }
@Override public void didEnterRegion(Region region) { Log.d(TAG, "I just saw a beacon named " + region.getUniqueId() + " for the first time!"); try { Log.d(TAG, "entered region. starting ranging"); mBeaconManager.startRangingBeaconsInRegion(mAllBeaconsRegion); mBeaconManager.setRangeNotifier(this); } catch (RemoteException e) { Log.e(TAG, "Cannot start ranging"); } }
@Override public void onActivityStopped(Activity activity) { if (activity instanceof ScannerActivity) { isScannerActivityResumed = false; scannerActivityDestroyedTimestamp = SystemClock.elapsedRealtime(); long delayBetweenScans = getDelayBetweenScans(); Timber.d("setBackgroundBetweenScanPeriod to %d ", delayBetweenScans); beaconManager.setBackgroundBetweenScanPeriod(delayBetweenScans); beaconManager.setBackgroundMode(true); Timber.d("setBackgroundMode"); } }
@Override public void onCreate() { mAllBeaconsRegion = new Region("all beacons", null, null, null); mBeaconManager = BeaconManager.getInstanceForApplication(this); mBackgroundPowerSaver = new BackgroundPowerSaver(this); mRegionBootstrap = new RegionBootstrap(this, mAllBeaconsRegion); /* ibeacon layout */ mBeaconManager.setForegroundScanPeriod(500); mBeaconManager .getBeaconParsers() .add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); }
@Override public void didEnterRegion(Region arg0) { // In this example, this class sends a notification to the user whenever a Beacon // matching a Region (defined above) are first seen. Log.d(TAG, "did enter region."); try { // start ranging for beacons. This will provide an update once per second with the estimated // distance to the beacon in the didRAngeBeaconsInRegion method. mBeaconManager.startRangingBeaconsInRegion(arg0); mBeaconManager.setRangeNotifier(this); } catch (RemoteException e) { } }
public BeaconSearcher(Context context) { this.mContext = context.getApplicationContext(); this.mBeaconManager = BeaconManager.getInstanceForApplication(mContext); // 经过测试,天津的Beacon应该是Apple的Beacon,beaconTypeCode=0215 // 其传输帧的字节序列按照以下顺序传输,但是网络上查到2013年后的Estimote beacons也是下列的字节顺序,ok // mBeaconManager.getBeaconParsers().add(new // BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); // 也可能是AltBeacon(即Radius)的Beacon,ok mBeaconManager .getBeaconParsers() .add(new AltBeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); // 设置距离计算模型 DefaultDistanceCalcuator defaultDistanceCalcuator = new DefaultDistanceCalcuator(mContext); // 使用asserts/model-distance-calculations.json defaultDistanceCalcuator.setDefaultDistanceCalcuator(null); // 使用url // defaultDistanceCalcuator.setDefaultDistanceCalcuator("http://data.altbeacon.org/android-distance.json"); // 设置发现beacon监听回调,看到beacon,看不到beacon; 进入,离开,临界状态 // Specifies a class that should be called each time the BeaconService // sees or stops seeing a Region of beacons. // IMPORTANT: Only one MonitorNotifier may be active for a given // application. If two different activities or services set different // MonitorNotifier instances, the last one set will receive all the // notifications. mBeaconManager.setMonitorNotifier(mMonitorNotifier); // 设置测距修正回调,每个扫描周期结束,根据20秒内各beacon的RSSI平均值计算它的距离,该回调获取这些beacon的距离值 // Specifies a class that should be called each time the BeaconService // gets ranging data, which is nominally once per // second(实际上每个扫描周期,计算一次距离) when beacons are detected. // IMPORTANT: Only one RangeNotifier may be active for a given // application. If two different activities or services set different // RangeNotifier instances, // the last one set will receive all the notifications. mBeaconManager.setRangeNotifier(mRangeNotifier); // 当程序切换到后台,BeaconService自动切换到后台模式,为了省电,蓝牙扫描频率降低;程序恢复到前台,BeaconService也跟随恢复至前台 // simply constructing this class and holding a reference to it in your // custom Application // class will automatically cause the BeaconLibrary to save battery // whenever the application // is not visible. This reduces bluetooth power usage by about 60% Context appContext = this.mContext.getApplicationContext(); mBackgroundPowerSaver = new BackgroundPowerSaver(appContext); }
public void onCreate() { super.onCreate(); BeaconManager beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this); // By default the AndroidBeaconLibrary will only find AltBeacons. If you wish to make it // find a different type of beacon, you must specify the byte layout for that beacon's // advertisement with a line like below. The example shows how to find a beacon with the // same byte layout as AltBeacon but with a beaconTypeCode of 0xaabb. To find the proper // layout expression for other beacon types, do a web search for "setBeaconLayout" // including the quotes. // // beaconManager.getBeaconParsers().add(new BeaconParser(). // setBeaconLayout("m:2-3=aabb,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25")); // beaconManager .getBeaconParsers() .add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24")); Log.d(TAG, "setting up background monitoring for beacons and power saving"); // wake up the app when a beacon is seen // Region region = new Region("backgroundRegion", null, null, null); ArrayList<Region> regionList = new ArrayList<Region>(); regionList.add( new Region( "1", Identifier.parse(getString(R.string.uuid)), Identifier.parse(getString(R.string.major)), Identifier.parse("1"))); regionList.add( new Region( "2", Identifier.parse(getString(R.string.uuid)), Identifier.parse(getString(R.string.major)), Identifier.parse("2"))); regionList.add( new Region( "3", Identifier.parse(getString(R.string.uuid)), Identifier.parse(getString(R.string.major)), Identifier.parse("3"))); regionBootstrap = new RegionBootstrap(this, regionList); // simply constructing this class and holding a reference to it in your custom Application // class will automatically cause the BeaconLibrary to save battery whenever the application // is not visible. This reduces bluetooth power usage by about 60% backgroundPowerSaver = new BackgroundPowerSaver(this); // If you wish to test beacon detection in the Android Emulator, you can use code like this: // BeaconManager.setBeaconSimulator(new TimedBeaconSimulator() ); // ((TimedBeaconSimulator) BeaconManager.getBeaconSimulator()).createTimedSimulatedBeacons(); }
@Override public void onBeaconServiceConnect() { beaconManager.setRangeNotifier( new RangeNotifier() { @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { beaconRangeChange(beacons, region); } }); try { beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null)); } catch (RemoteException e) { } }
public void startBeaconMonitoring() { verifyBluetooth(); for (String type : beaconTypes) { beaconManager.getBeaconParsers().add(getParser(type)); } Log.d(TAG, "Starting Beacon monitoring..."); Region region = new Region("backgroundRegion", null, null, null); regionBootstrap = new RegionBootstrap(this, region); backgroundPowerSaver = new BackgroundPowerSaver(context); beaconManager.bind(this); }
private void verifyBluetooth() { try { if (!BeaconManager.getInstanceForApplication(getApplicationContext()).checkAvailability()) { final AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext()); builder.setTitle("Bluetooth not enabled"); builder.setMessage("Please enable bluetooth in settings and restart this application."); builder.setPositiveButton(android.R.string.ok, null); builder.setOnDismissListener( new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { System.exit(0); } }); builder.show(); } } catch (RuntimeException e) { final AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext()); builder.setTitle("Bluetooth LE not available"); builder.setMessage("Sorry, this device does not support Bluetooth LE."); builder.setPositiveButton(android.R.string.ok, null); builder.setOnDismissListener( new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { System.exit(0); } }); builder.show(); } }
@Override public void onCreate() { super.onCreate(); // Allow scanning to continue in the background. backgroundPowerSaver = new BackgroundPowerSaver(this); beaconManager = BeaconManager.getInstanceForApplication(this); }
@Override public void onActivityResumed(Activity activity) { ++this.activeActivityCount; if (activity instanceof ScannerActivity) { beaconManager.setBackgroundMode(false); isScannerActivityResumed = true; // the scanner activity runs in foreground mode, fast scanning Timber.d("setForegroundMode"); } else { // the app is still active but scan is backgrounded indefinitely beaconManager.setBackgroundBetweenScanPeriod(DELAY_FOREVER); isScannerActivityResumed = false; Timber.d("setBackgroundBetweenScanPeriod to %d ", DELAY_FOREVER); beaconManager.setBackgroundMode(true); Timber.d("setBackgroundMode"); } }
@Override public void onTerminate() { super.onTerminate(); // release whatever is needed mBeaconManager.unbind(this); mBeaconManager = null; SugarContext.terminate(); }
private RangingData(Parcel in) { BeaconManager.logDebug(TAG, "parsing RangingData"); Parcelable[] parcelables = in.readParcelableArray(this.getClass().getClassLoader()); beacons = new ArrayList<Beacon>(parcelables.length); for (int i = 0; i < parcelables.length; i++) { beacons.add((Beacon) parcelables[i]); } region = in.readParcelable(this.getClass().getClassLoader()); }
@Override public void onReceive(Context context, Intent intent) { BeaconManager.logDebug(TAG, "onReceive called in startup broadcast receiver"); if (android.os.Build.VERSION.SDK_INT < 18) { Log.w( TAG, "Not starting up beacon service because we do not have SDK version 18 (Android 4.3). We have: " + android.os.Build.VERSION.SDK_INT); return; } BeaconManager beaconManager = BeaconManager.getInstanceForApplication(context.getApplicationContext()); Intent startServiceIntent = new Intent(context, BeaconService.class); context.startService(startServiceIntent); startServiceIntent = new Intent(context, BeaconIntentProcessor.class); context.startService(startServiceIntent); }
public void stopMonitoringRegion(Region regionToStopMonitoring) { org.altbeacon.beacon.Region stoppedMonitorRegion = getAltBeaconRegionFromWMRegion(regionToStopMonitoring); try { mBeaconManager.stopRangingBeaconsInRegion(stoppedMonitorRegion); } catch (RemoteException e) { Log.println(Log.ERROR, "stopMonitoringRegion", e.getMessage()); } }
@Override public void onBeaconServiceConnect() { try { mBeaconManager.startRangingBeaconsInRegion( new org.altbeacon.beacon.Region("all", null, null, null)); } catch (RemoteException e) { Log.println(Log.ERROR, "onBeaconServiceConnect", e.getMessage()); } }
public org.altbeacon.beacon.Region startMonitoringRegion(Region regionToStartMonitoring) { org.altbeacon.beacon.Region newMonitoredRegion = getAltBeaconRegionFromWMRegion(regionToStartMonitoring); try { mBeaconManager.startMonitoringBeaconsInRegion(newMonitoredRegion); } catch (RemoteException e) { Log.println(Log.ERROR, "startMonitoringRegion", e.getMessage()); } return newMonitoredRegion; }
public class RangingActivity extends Activity { protected static final String TAG = "RangingActivity"; private BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ranging); } @Override protected void onDestroy() { super.onDestroy(); } @Override protected void onPause() { super.onPause(); // Tell the Application not to pass off ranging updates to this activity ((BeaconReferenceApplication) this.getApplication()).setRangingActivity(null); } @Override protected void onResume() { super.onResume(); // Tell the Application to pass off ranging updates to this activity ((BeaconReferenceApplication) this.getApplication()).setRangingActivity(this); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); } public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { if (beacons.size() > 0) { EditText editText = (EditText) RangingActivity.this.findViewById(R.id.rangingText); for (Beacon beacon : beacons) { logToDisplay( "Beacon " + beacon.toString() + " is about " + beacon.getDistance() + " meters away, with Rssi: " + beacon.getRssi()); } } } private void logToDisplay(final String line) { runOnUiThread( new Runnable() { public void run() { EditText editText = (EditText) RangingActivity.this.findViewById(R.id.rangingText); editText.append(line + "\n"); } }); } }
@Override public void onReceive(Context context, Intent intent) { if (!Adbeacon.isAllowService(context)) return; try { if (Adbeacon.isOnline(context) && BeaconManager.getInstanceForApplication(context).checkAvailability()) context.startService(new Intent(context, AdbeaconService.class)); } catch (RuntimeException e) { } }
/** Called when no beacons in a Region are visible. */ @Override public void didExitRegion(Region region) { LogManager.d(TAG, "didExitRegion(),region uniqueId= " + region.getUniqueId()); /** * Tells the BeaconService to stop looking for beacons that match the passed Region object * and providing mDistance information for them. */ try { mBeaconManager.stopRangingBeaconsInRegion(ALL_VOLIAM_BEACONS_REGION); } catch (RemoteException e) { LogManager.d(TAG, "RemoteException:" + e.toString()); } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.user); beaconManager = BeaconManager.getInstanceForApplication(this); 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")); beaconManager.bind(this); logToDisplay(userTypeActivity.userTypeDef); sendRequest = (Button) findViewById(R.id.sendRequest); sendRequest.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { onBeaconServiceConnect(); } }); }
/** * Called when the beacon service is running and ready to accept your commands through the * BeaconManager 开始查找beacon */ @Override public void onBeaconServiceConnect() { /** * Tells the BeaconService to start looking for beacons that match the passed Region * object. Note that the Region's unique identifier must be retained保存 to later call the * stopMonitoringBeaconsInRegion method. */ try { // 通知BeaconService,开始监控特定区域的Beacons,一旦检测到beacons,执行MonitorNotifier接口中的回调(进入,离开,临界) mBeaconManager.startMonitoringBeaconsInRegion(ALL_VOLIAM_BEACONS_REGION); } catch (RemoteException e) { LogManager.d(TAG, "RemoteException:" + e.toString()); } }
/** 查看手机蓝牙是否可用,若当前状态为不可用,则默认调用意图请求打开系统蓝牙 */ public boolean checkBLEEnable() throws BleNotAvailableException { try { if (mBeaconManager.checkAvailability()) { // 支持ble 且蓝牙已打开 return true; } else { // 支持ble 但蓝牙未打开 return false; } } catch (BleNotAvailableException e) { // 当设备没有bluetooth或没有ble时,会产生该异常 throw new BleNotAvailableException("Bluetooth LE not supported by this device"); } }
public ThunderBoardPowerSaver(Context context, PreferenceManager preferenceManager) { if (android.os.Build.VERSION.SDK_INT < 18) { Timber.d("BackgroundPowerSaver requires API 18 or higher."); return; } if (context instanceof Application) { ((Application) context).registerActivityLifecycleCallbacks(this); } else { Timber.e("Context is not an application instance, so we cannot use the BackgroundPowerSaver"); } this.preferenceManager = preferenceManager; this.beaconManager = BeaconManager.getInstanceForApplication(context); }
/** Called when at least one beacon in a Region is visible. */ @Override public void didEnterRegion(Region region) { LogManager.d(TAG, "didEnterRegion(),region uniqueId= " + region.getUniqueId()); /** * 启动测距修正 Tells the BeaconService to start looking for beacons that match the passed * Region object, and providing updates on the estimated mDistance every * seconds(实际上是每个扫描周期) while beacons in the Region are visible. Note that the Region's * unique identifier must be retained to later call the stopRangingBeaconsInRegion method. * this will provide an update once per second with the estimated distance to the beacon * in the didRAngeBeaconsInRegion method. */ try { mBeaconManager.startRangingBeaconsInRegion(ALL_VOLIAM_BEACONS_REGION); } catch (RemoteException e) { LogManager.d(TAG, "RemoteException:" + e.toString()); } }
@Override public void onBeaconServiceConnect() { // callback for when service connection is complete mBeaconManager.setBackgroundMode(true); }
public void stopScanning() { if (mBeaconManager != null && mBeaconManager.isBound(this)) mBeaconManager.unbind(this); }