Kontakt.io SDK:是否有一种方法可以在信标列表中进行硬编码,以便在需要搜索信标时可以从它们中随机提取?

时间:2019-05-04 04:21:28

标签: java ibeacon-android kontakt.io

我正在编写一个应用程序,旨在通过向信标分配问题来帮助孩子们起床并在教室里活跃起来。该应用程序的工作方式如下:

  1. 从api输入游戏代码(类似于Kahoot)
  2. 开始扫描信标
  3. 找到某个信标并在其距离之内时,进入问题屏幕并询问用户必须回答的问题。
  4. 重复步骤2和3,直到没有问题为止。

有问题的问题来自流程的第二步。我正在寻找我拥有的所有信标的列表(或者硬编码到应用程序中,或者即时收集它们),以便我可以轻松地选择一个随机信标,让用户去寻找该信标来回答下一个问题。当我尝试在信标中进行硬编码时,距离不起作用(它只读取0.0),当我尝试在应用程序运行时收集它们时,只要信标更新,应用程序就会崩溃或挂起。我正在使用Kontakt Android SDK。

我尝试将for循环放入onIBeaconsUpdated中以从更新的信标列表中收集并从随机选择的信标中选择,但是它会不断更改它正在寻找的信标,因此不可能供用户完成。

我还尝试过使用Kontakt.io Web面板上信标的详细信息来列出信标列表,但是我必须缺少将这些生成的信标链接到物理信标或其他东西的步骤,因为listOfHardcodedBeacons.get(0).getDistance()将无论您在看哪个信标,或者距信标有多远,总是返回0.0。

请原谅我糟糕的代码:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_scanner);
        distanceTV = findViewById(R.id.distanceText);
        setupProximityManager();
        fillBeaconList(listOfHardcodedBeacons);
        randint = random.nextInt(listOfHardcodedBeacons.size());

        super.onCreate(savedInstanceState);
    }

    private void fillBeaconList(List<IBeaconDevice> beaconList) {

        //beacon #1
        BeaconDevice beacon1 = new BeaconDevice.Builder()
                .uniqueId("q0hg")
                .proximityUUID(UUID.fromString("f7826da6-4fa2-4e98-8024-bc5b71e0893e"))
                .major(1)
                .minor(0)
                .address("D3:95:F8:1E:CB:6E")
                .build();

        //beacon #2
        BeaconDevice beacon2 = new BeaconDevice.Builder()
                .uniqueId("eHI1")
                .proximityUUID(UUID.fromString("f7826da6-4fa2-4e98-8024-bc5b71e0893e"))
                .major(1)
                .minor(1)
                .address("CF:FE:16:60:0D:50")
                .build();

        //beacon #3
        BeaconDevice beacon3 = new BeaconDevice.Builder()
                .uniqueId("R9Bq")
                .proximityUUID(UUID.fromString("f7826da6-4fa2-4e98-8024-bc5b71e0893e"))
                .major(1)
                .minor(2)
                .address("CF:81:E3:B6:D1:D0")
                .build();

        //beacon #4
        BeaconDevice beacon4 = new BeaconDevice.Builder()
                .uniqueId("zUiD")
                .proximityUUID(UUID.fromString("f7826da6-4fa2-4e98-8024-bc5b71e0893e"))
                .major(55910)
                .minor(12620)
                .address("DC:65:69:47:93:26")
                .build();

        //beacon #5
        BeaconDevice beacon5 = new BeaconDevice.Builder()
                .uniqueId("QR18")
                .proximityUUID(UUID.fromString("f7826da6-4fa2-4e98-8024-bc5b71e0893e"))
                .major(30785)
                .minor(10106)
                .address("D7:1F:B8:AF:85:B2")
                .build();

        //beacon #6
        BeaconDevice beacon6 = new BeaconDevice.Builder()
                .uniqueId("uhnG")
                .proximityUUID(UUID.fromString("f7826da6-4fa2-4e98-8024-bc5b71e0893e"))
                .major(48261)
                .minor(35926)
                .address("CC:2C:82:59:93:C6")
                .build();

        beaconList.add(beacon1);
        beaconList.add(beacon2);
        beaconList.add(beacon3);
        beaconList.add(beacon4);
        beaconList.add(beacon5);
        beaconList.add(beacon6);
    }

    //TODO: figure out list of known beacons and do stuff
    private IBeaconListener createIBeaconListener() {

        return new IBeaconListener() {
            @Override
            public void onIBeaconDiscovered(IBeaconDevice ibeacon, IBeaconRegion region) {

                //Toast.makeText(getApplicationContext(), String.format("I found beacon %s! :D", ibeacon.getUniqueId()), Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onIBeaconsUpdated(List<IBeaconDevice> ibeaconList, IBeaconRegion region) {

                /* This was my original code. It pulls the closest beacon. It isn't what I want because I don't want the user to keep pulling questions from the same beacon.

                String rounded = df.format(ibeaconList.get(0).getDistance());
                distanceTV.setText(String.format("Distance to %s: ", ibeaconList.get(0).getUniqueId()) + rounded);
                if(ibeaconList.get(0).getDistance() <= 2.7432) { //2.7432 = 9 feet
                    distanceTV.setText("Found it! :D");
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            toQuestions();
                        }
                    }, 1000);
                    proximityManager.stopScanning();
                }
                */

            }

            @Override
            public void onIBeaconLost(IBeaconDevice ibeacon, IBeaconRegion region) {
                //Toast.makeText(getApplicationContext(), String.format("I lost beacon %s! D:", ibeacon.getUniqueId()), Toast.LENGTH_SHORT).show();
            }

        };
    }

    public void toQuestions() {

        Intent intent = new Intent(this, QuestionActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        this.startActivity(intent);
        finish();
    }

到目前为止,代码只会从ibeaconList中的第一个信标中提取,并告诉用户转到该信标,但这对于应用程序的目标而言并不理想。如前所述,我想从预定义信标的随机列表中拉出,然后随机地随机浏览列表。我已经针对我的问题编写并删除了4种可能无法正常工作的解决方案,但是我不确定目前该怎么做。任何帮助,将不胜感激。我尽力使这一点尽可能清楚,但是如果您仍然需要更多信息,我将很乐意提供。

1 个答案:

答案 0 :(得分:0)

对于任何可能阅读此书的人,我都找到了答案。我所做的就是:

IBeaconFilter filter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_scanner);
        distanceTV = findViewById(R.id.distanceText);
        fillBeaconList(listOfHardcodedBeacons);
        randint = random.nextInt(listOfHardcodedBeacons.size());
        filter = new IBeaconUniqueIdFilter(listOfHardcodedBeacons.get(randint).getUniqueId());

        setupProximityManager();

        super.onCreate(savedInstanceState);
    }

private void setupProximityManager(){
        proximityManager = ProximityManagerFactory.create(this);

        //configure proximity manager basic options
        proximityManager.configuration()
                //using ranging for continuous scanning or MONITORING for scanning with intervals
                .scanPeriod(ScanPeriod.RANGING)
                //using BALANCED for best performance/battery ratio
                .scanMode(ScanMode.LOW_LATENCY)
                //OnDeviceUpdate callback will be received with 1 second interval
                .deviceUpdateCallbackInterval(TimeUnit.MILLISECONDS.toMillis(20));

        //setting up iBeacon and Eddystone spaces listeners
        //proximityManager.setSpaceListener(createSpaceListener());

        //setting up iBeaconListener to only listen for random beacon (filter)
        proximityManager.filters().iBeaconFilter(filter);
        proximityManager.setIBeaconListener(createIBeaconListener());
        proximityManager.setEddystoneListener(new SimpleEddystoneListener() {
        });

    }

这使我将现有(注释的)代码保留在onIBeaconsUpdated中,而没有任何混乱的列表。此解决方案采用在Activity开始时创建的随机int,然后将其用作硬编码信标列表的索引,然后将其用作过滤器的uniqueID。当Proximity Manager开始扫描时,它将仅检测到该uniqueID的信标。这是我在其他任何地方都没见过的解决方案,因此我在这里张贴是为后代。