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