0

我试图在信标上构建一个应用程序。所以我从这里得到了一个示例代码。

我已经运行了该代码,一旦我进入信标范围,应用程序就会崩溃,logcat 中的错误如下:

06-20 17:48:24.256: E/AndroidRuntime(18104): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

请帮帮我。

我检查了代码,错误就在这两行之间。

iBeaconManager.setRangeNotifier(new RangeNotifier() {
        @Override
        public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons, Region region) {
            if (iBeacons.size() > 0) {
                double distance = iBeacons.iterator().next().getAccuracy();
                DecimalFormat decimalFormat = new DecimalFormat("##.##");
                double distanceFormatted = Double.valueOf(decimalFormat.format(distance));
                TextView distanceTextView = (TextView) findViewById(R.id.am_tv_distance);
                distanceTextView.setText(String.valueOf(distanceFormatted) + " m");
            }
        }
    });
4

2 回答 2

1

您需要在 UI 线程中执行 UI 更改:

    iBeaconManager.setRangeNotifier(new RangeNotifier() {
    @Override
    public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons, Region region) {
        if (iBeacons.size() > 0) {
            double distance = iBeacons.iterator().next().getAccuracy();
            DecimalFormat decimalFormat = new DecimalFormat("##.##");
            double distanceFormatted = Double.valueOf(decimalFormat.format(distance));
            runOnUiThread(new Runnable() {

                  @Override
                  public void run() {
                        TextView distanceTextView = (TextView) findViewById(R.id.am_tv_distance);
                        distanceTextView.setText(String.valueOf(distanceFormatted) + " m");
                  }
            });
         }
    }
});
于 2014-06-20T12:23:20.860 回答
0

对于CalledFromWrongThreadException,

编写一个函数并调用它:

private void toastToDisplay(final String line) {
    runOnUiThread(new Runnable() {
        public void run() {
            //Toast.makeText(YourActivity.this, "" + line,
                    // Toast.LENGTH_LONG).show();
            TextView yourTextView = (TextView) findViewById(R.id.your_tv);
            yourTextView .setText(line);
        }
    });
}  

如果需要,您可以使用所需的distanceTextView视图或其他视图编辑该函数。发生的情况是服务在应用程序的后台线程上运行,因此当您直接调用将更新 UI 的操作时,它与您在编写该代码时所在的线程发生冲突。

所以如果当前线程不是UI线程,则使用runOnUiThread将动作发布到UI线程的事件队列中

“我得到的只是距离而不是范围”到底是什么意思?...对于iBeacons.iterator().next().getAccuracy();, 部分.. 您可以使用 for each 循环来收集信标详细信息,例如:

for (IBeacon iBeacon : iBeacons) {
String line = "Major: " + iBeacon.getMajor()
                                    + "Minor: " + iBeacon.getMinor()
                                    + "Accuracy in m(s): "
                                    + iBeacon.getAccuracy()
                                    + "BluetoothAddress: "
                                    + iBeacon.getBluetoothAddress()
                                    + "Proximity: " + iBeacon.getProximity()
                                    + "ProximityUuid: "
                                    + iBeacon.getProximityUuid() + "Rssi: "
                                    + iBeacon.getRssi() + "TxPower: "
                                    + iBeacon.getTxPower(); 
toastToDisplay(line);
    }  

如果您还没有看过它,这个 Android iBeacon 库示例应用程序是一个很好的参考。

于 2014-06-20T12:42:32.047 回答