2016-07-09 1 views
0

Ich möchte Beacon UUID, Major und Minor in der Listenansicht angezeigt. Wenn meine onServiceConnect() -Methode aufgerufen wird, fügt sie Elemente (UUID, Major, Minor-Werte) in die Liste ein. Obwohl es zeigt die Listenelemente, wenn ich meinen Code debuggen, aber mein app endet nach wenigen Sekunden mich mit diesem Fehler zu verlassen:Der Inhalt des Adapters wurde geändert, aber ListView hat keine Benachrichtigung erhalten.

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.

Hier ist mein Code

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

} 

Antwort

0

Das Problem wird durch die Manipulation der adapter verursacht wird oder die arrayList enthält es von jedem Thread, der nicht der UI-Thread ist. Es gibt mindestens eine Linie, die die arrayList in einem Beacon Rückruf ändert, die nicht auf dem UI-Thread ist:

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

Um das Problem zu beheben, müssen Sie wie unter dieser Zeile in einem Block wickeln. Um die beste Effizienz zu erzielen, sollten Sie die gesamte Beacon-Iterationsschleife in einen Block wie diesen umbrechen, sodass Sie innerhalb der Schleife nicht wiederholt einen neuen Runnable erstellen.

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

Sie müssen auch adapter.notifyDataSetChanged(); aus dem UI-Thread nennen die Änderungen wirksam werden zu lassen. Sie sollten das am Ende des Blocks hinzufügen.

Obwohl dies nicht Teil der Frage ist, ist es erwähnenswert, dass die folgende Zeile innerhalb der Schleife, die über iteriert, den Wert beacon auf das erste Element in der Liste festlegen. Diese Niederlagen wahrscheinlich den Zweck über beacons Laufens, so können Sie diese Zeile entfernen möchten:

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

ich die Methode runOnUiThread() implementiert, aber es hat nicht geklappt für me.I'm immer noch die gleichen Fehler –

Verwandte Themen