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必要に応じて、必要なビューまたは他のビューでその関数を編集できます。そこで何が起こるかというと、Service はアプリケーションのバックグラウンド スレッドで実行されているため、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 に答える