2016-07-09 19 views
0

リストビューで、検出されたビーコンのUUID、メジャー、マイナーを表示します。私のonServiceConnect()メソッドが呼び出されると、リストに項目(UUID、Major、Minor値)が追加されます。私は自分のコードをデバッグするとき、それは、リストの項目を示していますが、私のアプリは、このエラーで私を残して、数秒後に終了しますが:アダプタの内容は変更されましたが、ListViewは通知を受信しませんでした。

The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes.

ここで問題がadapterを操作によって引き起こされる自分のコード

public class NotifyDemo_Sc4 extends Activity implements BeaconConsumer { 
    private ListView list; 
    private ArrayList<String> arrayList; 
    Button buttonNotify,b2; 
    private BeaconManager beaconManager; 
    private BluetoothAdapter mBluetoothAdapter; 
    private static final String TAG = "MainActivity"; 
    private int nos_calls=0; 
    private boolean run_call=true; 
    Beacon beacon; 
    ArrayAdapter<String> adapter; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_notifydemo); 
     WebView view = (WebView) findViewById(R.id.myWebView3); 
     buttonNotify = (Button) findViewById(R.id.buttonViewNotific); 
     b2 = (Button) findViewById(R.id.buttondemo); 
     b2.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Intent i = new Intent(NotifyDemo_Sc4.this, HomeScreen.class); 
       startActivity(i); 
      } 
     }); 
     view.loadUrl("file:///android_asset/name.html"); 
     list = (ListView) findViewById(R.id.listview2); 
     arrayList = new ArrayList<String>(); 
     adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_spinner_item, arrayList); 
     list.setAdapter(adapter); 
     adapter.notifyDataSetChanged(); 
     runOnUiThread(new Runnable() { 
      public void run() { 
       adapter.notifyDataSetChanged(); 
      } 
     }); 

     // requestLayout(); 
     beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this); 
     beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25")); 
     beaconManager.bind(this); 

     beaconManager.setDebug(true); 
     beaconManager.setBackgroundScanPeriod(1100l); 
     beaconManager.setAndroidLScanningDisabled(false); 

     Log.d(TAG, "didEnterRegion" + beaconManager); 
     mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); 

     // Create the adapter to convert the array to views 
     // ArrayAdapter adapter = new ArrayAdapter<>(this, arrayOfDevices); 
     // Attach the adapter to a ListView 

    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     beaconManager.unbind(this); 
    } 

    @Override 
    public void onBeaconServiceConnect() { 
     blefunction(); 
     // nos_calls++; 
     final Region region = new Region("myBeaons", Identifier.parse("E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"), null, null); 
     // runOnUiThread(new Runnable() { 
     final Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       beaconManager.setRangeNotifier(new RangeNotifier() { 

        @Override 
        public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) { 
         for (Beacon beacon : beacons) { 
          beacon = beacons.iterator().next(); 
          String b = beacon.toString(); 
          double b2 = beacon.getDistance(); 
          Log.i(TAG, "The first beacon I see is about " + beacon.toString() + " Distance " + beacon.getDistance() + " meters away."); 
          Log.i(TAG, "Beacon Detected" + beacon.toString()); 
          arrayList.add("Beacon UUID, Major, Minor:" + b + "\n"); 
          Toast.makeText(getApplicationContext(), " The beacon " + "The distance " + beacon.getDistance() + " meters away.", Toast.LENGTH_SHORT); 
         } 
        } 
       }); 
      }}, 3000); 

      try 
      { 
       beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", Identifier.parse("E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"), Identifier.parse("0"), Identifier.parse("1"))); 
      } 
      catch(RemoteException e){} 
    } 
    void blefunction() 
    {if(run_call = true){ 
     mBluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() { 
      @Override 
      public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { 
       Log.d(TAG, "Scanned BLE device with mac: " + device.getAddress()); 
       String add = "C4:BE84:05:EE:BF"; 
       long e = System.currentTimeMillis(); 
       Log.i(TAG, "in " + (e) + "ms"); 
      // Toast.makeText(getApplicationContext(), "BLE Scanned Device Address: " + device.getAddress() + "/n" + "Time in milliseconds:" + e + " ms", Toast.LENGTH_SHORT).show(); 
       run_call = false; } 
     });}} 

} 

答えて

0

ですまたはarrayListには、UIスレッドではないスレッドからのものが含まれます。 UIスレッド上ではありませんビーコンコールバック、中arrayListを変化させる少なくとも1つのラインがあります:

arrayList.add("Beacon UUID, Major, Minor:" + b + "\n"); 

問題を解決するには、あなたは以下のようなブロックでその行をラップする必要があります。最高の効率を得るには、ビーコン反復ループ全体をこのようなブロックにラップする必要があります。したがって、ループ内に新しいRunnableを繰り返し作成することはありません。

runOnUiThread(new Runnable() { 
    public void run() { 
     ... 
    } 
}); 

また、変更を有効にするには、UIスレッドからadapter.notifyDataSetChanged();に電話する必要があります。それをブロックの最後に追加する必要があります。

これは質問の一部ではありませんが、beaconsを反復するループ内の次の行は、beaconの値をリストの最初の項目に設定することに注意してください。これはおそらくbeaconsを反復処理の目的に反し、あなたがその行を削除することがあります。

beacon = beacons.iterator().next(); 
+0

私は方法runOnUiThreadを(実装)が、それはme.I'mはまだ同じエラーを取得するためにうまくいきませんでした –

関連する問題