检测iBeacon并在Android中捕获详细信息

时间:2014-06-04 12:40:25

标签: android region ibeacon-android

我正在使用Radius Network提供的proximity-reference-android示例应用程序来检测iBeacon。我将iPad配置为iBeacon,并在感应套件中添加了大约3个信标区域。我现在面临的问题是我无法获取Beacon名称,以及我在Android中的感应套件中获得的额外网址。

我需要在Android应用程序中显示与该信号区域相关联的网址,就像iOS应用程序一样。

调试时我已经检查过,即使在应用程序中检测到信标后, didEnterRegion 也不会被调用。我需要基本上将该特定信标的详细信息保存在数据库中被检测到。

应用程序调用 didExitRegion

发布以下代码,请让我知道我在做错了什么。

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());

    }
}

以下代码属于 mainActivity

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);

            }
        });

    }

}

任何帮助都将不胜感激。谢谢:)

1 个答案:

答案 0 :(得分:1)

使用Proximity Kit for Android时,可以使用两组不同的API。一组使用ProximityKitManager,它用于更简单的用例,您可以预先配置所有iBeacon标识符和相关数据服务器端,并让ProximityKitManager处理设置范围和监视在全局Application类中。

第二组API使用IBeaconManager并提供更细粒度的控制。但由于ProximityKitManager使用了引擎盖下的IBeaconManager,因此您不应同时使用两者,因为您可以轻松地破坏ProximityKitManager完成的自动配置。我怀疑这是导致问题的原因,因为代码使用Application类中的ProximityKitManager和Activity类中的IBeaconManager。有关详细信息,请参阅here

如果您需要跟踪信标而不管ProximityKit中设置的标识符,但仍想访问为ProximityKit中的某些iBeacons配置的数据,则不应使用ProximityKitManager而只需使用{{1 }}。有一个参考应用程序,显示如何使用此API here.

访问ProximityKit数据