android - 在 Android 中检测 iBeacon 并捕获细节

标签 android region ibeacon-android

我正在使用 Radius Network 提供的 proximity-reference-android 示例应用程序来检测 iBeacon。我有一个配置为 iBeacon 的 iPad,并在接近套件中添加了大约 3 个信标区域。我现在面临的问题是我无法获取 Beacon 名称,以及我在 Android 的接近工具包中拥有的附加 url。

我基本上需要在 Android 应用程序的接近工具包中显示与信标区域关联的 url,就像 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());

    }
}

下面的代码属于ma​​inActivity

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

            }
        });

    }

}

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

最佳答案

使用 Proximity Kit for Android 时,有两组独立的 API 可用。一组使用 ProximityKitManager,它适用于更简单的用例,您可以预先配置所有 iBeacon 标识符和关联的数据服务器端,并让 ProximityKitManager在全局应用程序类中处理设置测距和监控。

第二组 API 使用 IBeaconManager 并提供更细粒度的控制。但是因为 ProximityKitManager 在底层使用了 IBeaconManager,所以你不应该同时使用两者,因为你很容易破坏 ProximityKitManager< 完成的自动配置。我怀疑这是导致问题的原因,因为代码在 Application 类中使用了 ProximityKitManager ,在 Activity 类中使​​用了 IBeaconManager 。参见 here了解更多信息。

如果您需要跟踪信标而不考虑 ProximityKit 中设置的标识符,但仍想访问为 ProximityKit 中的某些 iBeacon 配置的数据,则不应使用 ProximityKitManager,而应使用IBeaconManager。有一个引用应用程序展示了如何使用可用的 API 访问 ProximityKit 数据 here.

关于android - 在 Android 中检测 iBeacon 并捕获细节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24037716/

相关文章:

java - For 循环迭代器类型与我尝试访问的类型不同

android - 应用程序被终止时 Android 中的信标检测

android - 任何基于 Android ibeacon 的开源项目/库

android - Facebook 分享小姐 EXTRAS

android - Firebase 云消息传递设备 ID : multiple user in same app in same device

android - 为什么我们使用另一个继承binder类的类来访问BoundServices?

java - 解析博客文章

javascript - 有没有办法替换 c3 中的区域?

python - 如何使用 Altair 为区域着色

ios - 检测iphone地区