Обновление RecyclerView в BroadcastReceiver не работает - PullRequest
0 голосов
/ 27 апреля 2020

Я хочу, чтобы все устройства Bluetooth отображались в режиме переработчика. Поэтому я должен обновить свое представление программы перезапуска, если в onReceive было обнаружено соседнее устройство.

Я написал DeviceListAdapter и класс, чтобы определить мое устройство Bluetooth в одном файле.

class BluetoothItem internal constructor(_uuid:String, _macAddress: String){
    internal var bluetoothUuid:String? = _uuid
    internal var bluetoothMacAddress:String? = _macAddress
}

// Class to handle RecyclerView
class DeviceListAdapter internal constructor(_itemList:ArrayList<BluetoothItem>): RecyclerView.Adapter<RecyclerView.ViewHolder>(){
    private var itemList:ArrayList<BluetoothItem> = _itemList

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val view: View = LayoutInflater.from(parent.context).inflate(R.layout.item_devices, parent, false)
        return ViewHolder(view)
    }

    override fun getItemCount(): Int {
        return if(itemList == null) 0 else itemList!!.size
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        initLayout(holder as ViewHolder, position)
    }

    private fun initLayout(holder:ViewHolder, pos:Int){
        holder.deviceName.text = itemList!![pos].bluetoothMacAddress
    }
    internal class ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
        var deviceName:TextView = itemView.device as TextView
    }
}

My Деятельность выглядит следующим образом:

class PrinterActivity: AppCompatActivity() {
    private val blueAdapter = BluetoothAdapter.getDefaultAdapter()
    private var itemList = ArrayList<BluetoothItem>()
    private var itemArrayAdapter = DeviceListAdapter(itemList)
    private val layoutMng = LinearLayoutManager(this)

    // ############################ Activity ################################
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_printer)

        // prepare the recyclerview and assign the arrayAdapter to the recyclerview
        device_list!!.layoutManager = layoutMng
        device_list!!.itemAnimator = DefaultItemAnimator()
        device_list!!.adapter = itemArrayAdapter

        if (blueAdapter!!.isDiscovering) {
            blueAdapter.cancelDiscovery()
            blueAdapter.startDiscovery()
            val deviceIntent = IntentFilter(BluetoothDevice.ACTION_FOUND)
            registerReceiver(mBroadcastRec, deviceIntent)
        }
        if (!blueAdapter.isDiscovering) {
            blueAdapter.startDiscovery()
            val deviceIntent = IntentFilter(BluetoothDevice.ACTION_FOUND)
            registerReceiver(mBroadcastRec, deviceIntent)
        }
    }

    // ########################## Functions ##############################
    override fun onDestroy() {
        super.onDestroy()
        //destroy receiver
        unregisterReceiver(mBroadcastRec)
    }

    // ########################## Broadcaster ##############################
    private val mBroadcastRec: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            // When discovery finds a device
            if (action == BluetoothDevice.ACTION_FOUND) {
                val device: BluetoothDevice? = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)          
                // update
                if (device != null && device_list.adapter != null) {
                    itemList.add(BluetoothItem(device.name, device.address))
                    device_list.adapter!!.notifyDataSetChanged()
                }
            }

        }
    }
}

Мой xml -файл:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">



    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/device_list"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Я видел в переполнении стека, что я должен уведомить свой адаптер с помощью notifyDataSetChanged ( ) Но я получаю исключение RuntimeException в приемнике.

Я не знаю, почему или что изменить. Ошибка возникает:

itemList.add(BluetoothItem(device.name, device.address))

со следующим исключением:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.driverapppro, PID: 10044
    java.lang.RuntimeException: Error receiving broadcast Intent { act=android.bluetooth.device.action.FOUND flg=0x10 pkg=com.example.driverapppro (has extras) } in com.example.driverapppro.PrinterActivity$mBroadcastRec$1@f95681a
        at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1566)
        at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7520)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
     Caused by: java.lang.IllegalStateException: device.name must not be null
        at com.example.driverapppro.PrinterActivity$mBroadcastRec$1.onReceive(PrinterActivity.kt:62)
        at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1556)

Спасибо за вашу помощь, ребята .. Я пытался найти ответ в разных темах при переполнении стека, но Я не могу это исправить. Может быть, у вас, ребята, есть идея.

Лучший

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...