RecyclerView crushes when using notifyDataSetChanged()

35 Views Asked by At

I created this app to show two recycler views, one containing paired devices and the other containing nearby available devices. The app works as intended until the ACTION_FOUND broadcast receiver is called, when a new device is added to the list, the app suddenly crashes. Why does this happen?

Broadcast receiver code:

private final BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            Log.d("Broadcast", "Broadcast called");
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                final String deviceName = device.getName();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (deviceName != null) {
                            availableDevices.add(deviceName);
                            adapter2.notifyDataSetChanged();
                        }
                    }
                });

            }
        }
    };

This is my whole code:

package com.example.wheelchairapp;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.graphics.PaintKt;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Bundle;
import android.os.health.PackageHealthStats;
import android.util.Log;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Set;

import android.Manifest;

public class DevicesList extends AppCompatActivity {
    ActionBar actionBar;
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    ArrayList<String> availableDevices;
    RecyclerView.Adapter adapter2;
    private static final int REQUEST_BLUETOOTH_PERMISSION = 1001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_devices_list);
        actionBarSet();
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        availableDevices = new ArrayList<String>();
        recycler1ViewSettings(getPairedDevices());
        recycler2ViewSettings();
        registerReceiver(receiver, filter);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
        && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            bluetoothAdapter.startDiscovery();
            if (!bluetoothAdapter.isDiscovering()){
                Toast.makeText(this, "Not Discovering", Toast.LENGTH_SHORT).show();
            }
            else if(bluetoothAdapter.isDiscovering()) {
                Toast.makeText(this, "Discovering", Toast.LENGTH_SHORT).show();
            }
        }
        else {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_BLUETOOTH_PERMISSION);
            bluetoothAdapter.startDiscovery();
            if (!bluetoothAdapter.isDiscovering()){
                Toast.makeText(this, "isn't Discovering", Toast.LENGTH_SHORT).show();
            }
            else if(bluetoothAdapter.isDiscovering()) {
                Toast.makeText(this, "Discovery started from else", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        bluetoothAdapter.cancelDiscovery();
        unregisterReceiver(receiver);
    }

    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            Log.d("Broadcast", "Broadcast called");
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                final String deviceName = device.getName();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (deviceName != null) {
                            availableDevices.add(deviceName);
                            adapter2.notifyDataSetChanged();
                        }
                    }
                });

            }
        }
    };

    private String[] getPairedDevices() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            Set<BluetoothDevice> bt = bluetoothAdapter.getBondedDevices();
            String[] pairedDevices = new String[bt.size()];
            int i = 0;
            for(BluetoothDevice d : bt){
                pairedDevices[i] = d.getName();
                i++;
            }
            return pairedDevices;
        }
        else{
            return new String[0];
        }
    }
    private void recycler1ViewSettings(String[] pairedDevices){
        RecyclerView recyclerView = findViewById(R.id.recyclerList1);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        RecyclerView.Adapter adapter = new CustomAdapter (pairedDevices, DevicesList.this);
        recyclerView.setAdapter(adapter);
    }

    private void recycler2ViewSettings(){
        RecyclerView recyclerView2 = findViewById(R.id.recyclerList2);
        recyclerView2.setHasFixedSize(true);
        recyclerView2.setLayoutManager(new LinearLayoutManager(this));
        adapter2 = new CustomAdapter2(availableDevices, this);
        recyclerView2.setAdapter(adapter2);
    }
    private void actionBarSet(){
        actionBar = getSupportActionBar();
        assert actionBar != null;
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeAsUpIndicator(R.drawable.baseline_arrow_back_24);
    }

}
0

There are 0 best solutions below