Question

I am using the proximity-reference-android sample application provided by Radius Network to detect an iBeacon. I have an iPad configured as an iBeacon and have added around 3 beacon regions in the proximity kit. The problem I am facing right now I am unable to fetch the Beacon name ,and the additional url which I had in the proximity kit in Android.

I need to basically show up the url associated with beacon region in that proximity kit in Android App just like how the iOS application does.

While Debugging I had checked that even after the beacon is detected in the application,the didEnterRegion doesn't get called.I need to basically save the details of that particular beacon in the database once it is detected.

Neither is the application calling didExitRegion.

Posting the below code,please let me know what I am doing wrong in this.

public class AndroidProximityReferenceApplication extends Application implements
        BootstrapNotifier {
    private static final String TAG = "AndroidProximityReferenceApplication";
    private RegionBootstrap regionBootstrap;
    private BackgroundPowerSaver backgroundPowerSaver;
    private boolean haveDetectedIBeaconsSinceBoot = false;

    public void onCreate() {
        super.onCreate();
        Log.d(TAG,
                "setting up background monitoring for iBeacons and power saving");

        // wake up the app when an iBeacon is seen
        Region region = new Region(
                "com.radiusnetworks.androidproximityreference.backgroundRegion",
                "2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6", null, null);
        regionBootstrap = new RegionBootstrap(this, region);

        // simply constructing this class and holding a reference to it in your
        // custom Application
        // class will automatically cause the iBeaconLibrary to save battery
        // whenever the application
        // is not visible. This reduces bluetooth power usage by about 60%
        backgroundPowerSaver = new BackgroundPowerSaver(this);
    }

    @Override
    public void didDetermineStateForRegion(int arg0, Region arg1) {
        // This method is not used in this example
    }

    @Override
    public void didEnterRegion(Region arg0) {
        // In this example, this class sends a notification to the user whenever
        // an iBeacon
        // matching a Region (defined above) are first seen.
        Log.d(TAG, "did enter region.");
        if (!haveDetectedIBeaconsSinceBoot) {
            Log.d(TAG, "auto launching MainActivity");

            // The very first time since boot that we detect an iBeacon, we
            // launch the
            // MainActivity
            Intent intent = new Intent(this, MainActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            // Important: make sure to add android:launchMode="singleInstance"
            // in the manifest
            // to keep multiple copies of this activity from getting created if
            // the user has
            // already manually launched the app.
            this.startActivity(intent);
            haveDetectedIBeaconsSinceBoot = true;
        } else {
            // If we have already seen iBeacons and launched the MainActivity
            // before, we simply
            // send a notification to the user on subsequent detections.
            Log.d(TAG, "Sending notification.");
            ParseObject beacon = new ParseObject("Beacon");
            beacon.put("beacon_name", arg0.getClass().getName());
            beacon.put("beacon_id", arg0.getUniqueId());
            beacon.put("device_type", "Android");
            beacon.put("device_UUID", android.os.Build.MODEL);
            beacon.put("beacon_status", "ENTRY");
            beacon.saveInBackground();

            sendNotification();
        }

    }

    @Override
    public void didExitRegion(Region arg0) {
        Log.d(TAG, "exited region");
        ParseObject beacon = new ParseObject("Beacon");
        beacon.put("beacon_name", arg0.getClass().getName());
        beacon.put("beacon_id", arg0.getUniqueId());
        beacon.put("device_type", "Android");
        beacon.put("device_UUID", android.os.Build.MODEL);
        beacon.put("beacon_status", "ENTRY");
        beacon.saveInBackground();

    }

    private void sendNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(
                this).setContentTitle("Proximity Reference Application")
                .setContentText("An iBeacon is nearby.")
                .setSmallIcon(R.drawable.ic_launcher);

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addNextIntent(new Intent(this, MainActivity.class));
        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(resultPendingIntent);
        NotificationManager notificationManager = (NotificationManager) this
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(1, builder.build());

    }
}

The code below is of the mainActivity class

public class MainActivity extends Activity implements IBeaconConsumer,
        RangeNotifier, IBeaconDataNotifier {
    public static final String TAG = "MainActivity";

    IBeaconManager iBeaconManager;
    Map<String, TableRow> rowMap = new HashMap<String, TableRow>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Parse.initialize(this, "test123",
                "test345");
        IBeaconManager.LOG_DEBUG = true;
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        iBeaconManager = IBeaconManager.getInstanceForApplication(this
                .getApplicationContext());
        iBeaconManager.bind(this);
    }

    @Override
    public void onIBeaconServiceConnect() {
        Region region = new Region("MainActivityRanging", null, null, null);
        try {
            iBeaconManager.startRangingBeaconsInRegion(region);
            iBeaconManager.setRangeNotifier(this);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        iBeaconManager.unBind(this);
    }

    @Override
    public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons,
            Region region) {
        for (IBeacon iBeacon : iBeacons) {
            iBeacon.requestData(this);
            Log.d(TAG, "I see an iBeacon: " + iBeacon.getProximityUuid() + ","
                    + iBeacon.getMajor() + "," + iBeacon.getMinor());
            String displayString = iBeacon.getProximityUuid() + " "
                    + iBeacon.getMajor() + " " + iBeacon.getMinor() + "\n";
            displayTableRow(iBeacon, displayString, false);

        }
    }

    @Override
    public void iBeaconDataUpdate(IBeacon iBeacon, IBeaconData iBeaconData,
            DataProviderException e) {
        if (e != null) {
            Log.d(TAG, "data fetch error:" + e);
        }
        if (iBeaconData != null) {
            Log.d(TAG,
                    "I have an iBeacon with data: uuid="
                            + iBeacon.getProximityUuid() + " major="
                            + iBeacon.getMajor() + " minor="
                            + iBeacon.getMinor() + " welcomeMessage="
                            + iBeaconData.get("welcomeMessage"));
            String displayString = iBeacon.getProximityUuid() + " "
                    + iBeacon.getMajor() + " " + iBeacon.getMinor() + "\n"
                    + "Welcome message:" + iBeaconData.get("welcomeMessage");
            displayTableRow(iBeacon, displayString, true);
        }
    }

    private void displayTableRow(final IBeacon iBeacon,
            final String displayString, final boolean updateIfExists) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TableLayout table = (TableLayout) findViewById(R.id.beacon_table);
                String key = iBeacon.getProximity() + "-" + iBeacon.getMajor()
                        + "-" + iBeacon.getMinor();
                TableRow tr = (TableRow) rowMap.get(key);
                if (tr == null) {
                    tr = new TableRow(MainActivity.this);
                    tr.setLayoutParams(new TableRow.LayoutParams(
                            TableRow.LayoutParams.WRAP_CONTENT,
                            TableRow.LayoutParams.WRAP_CONTENT));
                    rowMap.put(key, tr);
                    table.addView(tr);
                } else {
                    if (updateIfExists == false) {
                        return;
                    }
                }
                tr.removeAllViews();
                TextView textView = new TextView(MainActivity.this);
                textView.setText(displayString);
                tr.addView(textView);

            }
        });

    }

}

Any help would be appreciated.Thanks :)

Was it helpful?

Solution

When using Proximity Kit for Android, there are two separate sets of APIs available. One set uses a ProximityKitManager, and it is intended for simpler use cases where you can pre-configure all of your iBeacon identifiers and associated data server-side, and let the ProximityKitManager handle setting up ranging and monitoring in a global Application class.

The second set of APIs use the IBeaconManager and provide more fine-grained control. But because the ProximityKitManager uses the IBeaconManager under the hood, you should not use both at the same time, because you can easily break the automatic configuration done by ProximityKitManager. I suspect that is what is causing your problem, because the code uses the ProximityKitManager in the Application class and IBeaconManager in the Activity class. See here for more info.

If you need to track beacons regardless of the identifiers set up in ProximityKit, but still want to access the data configured for certain iBeacons in ProximityKit, you should not use the ProximityKitManager and instead just use the IBeaconManager. There is a reference application that shows how to access ProximityKit data using this API available here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top