这是正确的做法吗? AM使用此样本https://altbeacon.github.io/android-beacon-library/samples.html
public class App extends Application implements BootstrapNotifier, BeaconConsumer, RangeNotifier { private final String TAG = "Application "; protected static final Region beaconRegion = new Region("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6", null, null, null); protected BeaconManager beaconManager = null; private RegionBootstrap regionBootstrap; private BackgroundPowerSaver backgroundPowerSaver; protected static String sLog = ""; @Override public void onCreate() { super.onCreate(); logIt(TAG, beaconRegion.getId1()+"onCreate - In"+beaconRegion.getUniqueId()); 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"));//iBeacon (tutti) //--- wake up the app when a beacon is seen regionBootstrap = new RegionBootstrap(this, beaconRegion); //--- activate power saver backgroundPowerSaver = new BackgroundPowerSaver(this); beaconManager.bind(this); logIt(TAG, "onCreate - Out"); } private void logIt (String TAG, String msg) { sLog += TAG + msg + "\n"; Log.w(TAG, msg); } //-------------------------// //--- BootstrapNotifier ---// //-------------------------// @Override public void didDetermineStateForRegion(int state, Region region) { String msg = "didDetermineStateForRegion "; switch(state) { case MonitorNotifier.INSIDE: msg +="(INSIDE)"; break; case MonitorNotifier.OUTSIDE: msg +="(OUTSIDE)"; break; default: msg +="(state=" +state +")"; break; } logIt(TAG, msg); } @Override public void didEnterRegion(Region arg0) { logIt(TAG, "didEnterRegion - In"); try { beaconManager.startRangingBeaconsInRegion(beaconRegion); logIt(TAG,"dER - startRangingBeaconsInRegion OK"); } catch (RemoteException e) { logIt(TAG, "dER - startRangingBeaconsInRegion Err " +e); } logIt(TAG, "didEnterRegion - Out"); } @Override public void didExitRegion(Region region) { logIt(TAG, "didExitRegion - In"); try { beaconManager.stopRangingBeaconsInRegion(beaconRegion); logIt(TAG,"dXR - stopRangingBeaconsInRegion OK"); } catch (RemoteException e) { logIt(TAG, "dXR - stopRangingBeaconsInRegion Err " +e); } logIt(TAG, "didExitRegion - Out"); } //----------------------// //--- BeaconConsumer ---// //----------------------// @Override public void onBeaconServiceConnect() { logIt(TAG, "onBeaconServiceConnect - In"); beaconManager.setRangeNotifier(this); logIt(TAG, "onBeaconServiceConnect - Out"); } //---------------------// //--- RangeNotifier ---// //---------------------// @Override public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { logIt(TAG, "didRangeBeaconsInRegion - " +beacons.size() +" beacons"); Toast.makeText(getApplicationContext(), beaconRegion.getId1()+" beacon detected "+beacons.size(), Toast.LENGTH_SHORT).show(); for(Beacon beac: beacons) { System.out.println(beac.getId1()+"id 1"+TAG); if(beac.getId1().equals("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6")/send notification } } }
所以基本上这个扩展应用程序的类正在监听信标。下面是我如何将手机变成信标。我在点击按钮的活动中这样做。因此,有两个手机同时下载应用程序,一旦他点击一个应用程序按钮,我希望另一部手机检测到它,因为我已在扩展应用程序类中实现。
将你的android转为信标代码。
Beacon beacon = new Beacon.Builder() .setId1("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6") // UUID for beacon .setId2("1") // Major for beacon .setId3("5") // Minor for beacon .setManufacturer(0x004C) // Radius Networks.0x0118 Change this for other beacon layouts//0x004C for iPhone .setTxPower(-56) // Power in dB .setDataFields(Arrays.asList(new Long[]{0l})) // Remove this for beacon layouts without d: fields .build(); BeaconParser beaconParser = new BeaconParser() .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"); beaconTransmitter = new BeaconTransmitter(MenuActivity.this, beaconParser); beaconTransmitter.startAdvertising(beacon, new AdvertiseCallback() { @Override public void onStartFailure(int errorCode) { Log.e("tag", "Advertisement start failed with code: " + errorCode); } @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) { Log.i("tag", "Advertisement start succeeded."); Toast.makeText(MenuActivity.this, "advertisement start succeeded", Toast.LENGTH_SHORT).show(); System.out.println("startedddddddddddd"); } }); // beaconTransmitter.stopAdvertising(); } catch(Exception o) { System.out.println("affda "+o.getMessage()); }
我也是一个问题,didenterregion和didRangeBeaconsInRegion被多次触发,所以我多次向用户发送许多通知。它不是用户友好的。
答案 0 :(得分:2)
didRangeBeaconsInRegion
回调应该被多次调用 - 这是测距的工作原理。当检测到信标告诉你它在那里并给你一个距离估计时,大约每秒调用一次。
如果您第一次调用此方法时只想触发一次通知,则可以为此特定信标设置一个标志。
以下是您可能会使用的一些代码示例:
// Add this to the top of your class
private HashMap<String,Boolean> mAlreadySentNotification = new HashMap<String,Boolean>();
...
// Add this to the inside of your didRangeBeaconsInRegion method
if (mAlreadySentNotification.get(beacon.toString())) {
mAlreadySentNotification.put(beacon.toString(), true);
// Send notification here.
}