I have the following code and am trying to notify 5 in 5 seconds the distance traveled within the ibeacon area.
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.multidex.MultiDex;
import android.util.Log;
import android.os.Handler;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.Identifier;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import org.altbeacon.beacon.startup.BootstrapNotifier;
import org.altbeacon.beacon.startup.RegionBootstrap;
import java.util.ArrayList;
import java.util.Collection;
public class MyAppApplication extends Application implements BootstrapNotifier, BeaconConsumer {
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
private BeaconManager beaconManager;
private Beacon connectedBeacon;
private SharedPreferences prefs;
final Handler handler = new Handler();
private static boolean appIsForeground;
private Runnable r;
@Override
public void onCreate() {
super.onCreate();
MultiDex.install(getBaseContext());
prefs = getSharedPreferences(BuildConfig.SHARED_PREFS, Context.MODE_PRIVATE);
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(ConstantsMyApp.IBEACON_LAYOUT));
final ArrayList<Beacon> beaconArrayList = BeaconModel.selectAllBeacons(this); //get all ibeacons in the db
beaconManager.bind(this);
beaconManager.setMonitorNotifier(this);
beaconManager.setForegroundScanPeriod(5285);
beaconManager.setBackgroundBetweenScanPeriod(400);
for (Beacon savedBeacon: beaconArrayList) {
Region region = new Region(savedBeacon.getId() + "",
Identifier.parse(savedBeacon.getProximityUuid()),
Identifier.parse(savedBeacon.getMajor()),
Identifier.parse(savedBeacon.getMinor()));
regionBootstrap = new RegionBootstrap(this, region); //work to background app
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
Log.e("ERROR", e.toString());
}
}
backgroundPowerSaver = new BackgroundPowerSaver(this);
r = new Runnable() {
@Override
public void run() {
Log.i("INFO", "iBeacon distance " + connectedBeacon.getDistance());
handler.postDelayed(r, 5000);
}
};
}
@Override
public void didEnterRegion(Region region) {
if (region != null) {
connectedBeacon = BeaconModel.selectBeacon(this, region.getId2().toString(),
region.getId3().toString(),
region.getId1().toString());
}
if (connectedBeacon != null) {
Log.i("INFO", "Enter area iBeacon");
}
}
@Override
public void didExitRegion(Region region) {
if (region != null) {
connectedBeacon = BeaconModel.selectBeacon(this, region.getId2().toString(),
region.getId3().toString(),
region.getId1().toString());
}
if (connectedBeacon != null) {
if(handler != null) {
handler.removeCallbacks(runnable);
}
Log.i("INFO", "Exit area iBeacon");
}
}
@Override
public void didDetermineStateForRegion(int state, Region region) { }
@Override
public void onBeaconServiceConnect() {
Log.i("DEBUG+", "didRangeBeaconsInRegion: ");
beaconManager.setRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<org.altbeacon.beacon.Beacon> beacons, Region region) {
if (beacons.size() > 0) {
connectedBeacon = beacons.iterator().next();
String beaconUuid = connectedBeacon.getId1().toString();
String regionUuid = region.getId1().toString();
Log.i("DEBUG+", "beaconUuid: " + beaconUuid + " regionUuid " + regionUuid);
if(beaconUuid.equals(regionUuid)) {
if (connectedBeacon != null) {
Log.i("DEBUG+", "connectedBeacon.getId(): " + connectedBeacon.getId() +
" connectedBeacon.getDistance() " + connectedBeacon.getDistance());
handler.postDelayed(r, 5000);
}
}
}
}
});
}
public Activity getCurrentActivity() {
return currentActivity;
}
public void setCurrentActivity(Activity currentActivity) {
this.currentActivity = currentActivity;
}
public Beacon getConnectedBeacon(){
return connectedBeacon;
}
public static boolean isAppIsForeground() {
return appIsForeground;
}
public static void appResumed(){
appIsForeground = true;
}
public static void appPaused(){
appIsForeground = false;
}
}
I am using the library for this function on Android.
This notification must take place even with the app in the background.
Move the calls to beaconManager.startRangingBeaconsInRegion(region);
to happen after you get the onBeaconServiceConnected
callback. I suspect these calls are failing because the service is not bound yet, and the error messages are getting put in the logs.