BtMonitor Kotlin | #3

BtListActivity


import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import com.neco_desarrollo.btmonitorkotlin.databinding.ActivityMainBinding

class BtListActivity : AppCompatActivity(), RcAdapter.Listener {
private var btAdapter: BluetoothAdapter? = null
private lateinit var binding: ActivityMainBinding
private lateinit var adapter: RcAdapter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
init()
}

private fun init(){
val btManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
btAdapter = btManager.adapter
adapter = RcAdapter(this)
binding.rcView.layoutManager = LinearLayoutManager(this)
binding.rcView.adapter = adapter
getPairedDevises()
}

private fun getPairedDevises(){
val pairedDevices: Set<BluetoothDevice>? = btAdapter?.bondedDevices
val tempList = ArrayList<ListItem>()
pairedDevices?.forEach {
tempList.add(ListItem(it.name, it.address))
}
adapter.submitList(tempList)
}

companion object{
const val DEVICE_KEY = "device_key"
}

override fun onClick(item: ListItem) {
val i= Intent().apply {
putExtra(DEVICE_KEY, item)
}
setResult(RESULT_OK, i)
finish()
}
}

ControlActivity


import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.neco_desarrollo.btmonitorkotlin.databinding.ActivityControlBinding

class ControlActivity : AppCompatActivity() {
private lateinit var binding: ActivityControlBinding
private lateinit var actListLauncher: ActivityResultLauncher<Intent>

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityControlBinding.inflate(layoutInflater)
setContentView(binding.root)
onBtListResult()
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.control_menu, menu)
return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.id_list){
actListLauncher.launch(Intent(this, BtListActivity::class.java))
} else if(item.itemId == R.id.id_connect){

}
return super.onOptionsItemSelected(item)
}

private fun onBtListResult(){
actListLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()){
if(it.resultCode == RESULT_OK){
Log.d("MyLog","Name: ${(it.data?.getSerializableExtra(BtListActivity.DEVICE_KEY) as ListItem).name}")
}
}
}
}

AndroidManifies.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.neco_desarrollo.btmonitorkotlin">

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BtMonitorKotlin">
<activity
android:name=".ControlActivity"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".BtListActivity"
android:exported="true">
</activity>
</application>

</manifest>

RcAdapter


import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.neco_desarrollo.btmonitorkotlin.databinding.ListItemBinding


class RcAdapter(private val listener: Listener) : ListAdapter<ListItem, RcAdapter.ItemHolder>(ItemComparator()) {

class ItemHolder(view: View) : RecyclerView.ViewHolder(view){
val binding = ListItemBinding.bind(view)

fun setData(item: ListItem, listener: Listener) = with(binding){
tvName.text = item.name
tvMac.text = item.mac
itemView.setOnClickListener {
listener.onClick(item)
}
}
companion object{
fun create(parent: ViewGroup): ItemHolder{
return ItemHolder(LayoutInflater.
from(parent.context).
inflate(R.layout.list_item, parent, false))
}
}
}

class ItemComparator : DiffUtil.ItemCallback<ListItem>(){
override fun areItemsTheSame(oldItem: ListItem, newItem: ListItem): Boolean {
return oldItem.mac == newItem.mac
}

override fun areContentsTheSame(oldItem: ListItem, newItem: ListItem): Boolean {
return oldItem == newItem
}

}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {
return ItemHolder.create(parent)
}

override fun onBindViewHolder(holder: ItemHolder, position: Int) {
holder.setData(getItem(position), listener)
}

interface Listener{
fun onClick(item: ListItem)
}
}

control_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/id_connect"
android:title="Connect"
android:orderInCategory="100"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_connect"
/>
<item
android:id="@+id/id_list"
android:title="Bt List"
android:orderInCategory="200"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_list"
/>
</menu>

themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.BtMonitorKotlin" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/teal_700</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<item name="android:windowFullscreen">true</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

2 комментария для “BtMonitor Kotlin | #3”

  1. Здравствуйте. У меня проблема в данной частью кода:
    private fun getPairedDevices(){
    val pairedDevices: Set? = btAdapter?.bondedDevices
    val tempList = ArrayList()
    pairedDevices?.forEach {
    tempList.add(ListItem(it.name, it.address))
    }
    adapter.submitList(tempList)
    }

    …..

    btAdapter?.bondedDevices и it.name подчеркнуты красным и просят add permission check. Если нажать, то в код добавляется большой и страшный кусок кода 🙂 и все красное и там надо проверять какие-то условия. Что можно сделать с этим?
    Если что, то я добавил разрешения в Андройд манифест.
    Ниже добавлю кусок кода, который вставляется, если нажать на ошибку.
    Заранее спасибо!!!

    private fun getPairedDevices(){
    val pairedDevices: Set? = btAdapter?.bondedDevices
    val tempList = ArrayList()
    pairedDevices?.forEach {
    if (ActivityCompat.checkSelfPermission(
    this,
    Manifest.permission.BLUETOOTH_CONNECT
    ) != PackageManager.PERMISSION_GRANTED
    ) {
    // TODO: Consider calling
    // ActivityCompat#requestPermissions
    // here to request the missing permissions, and then overriding
    // public void onRequestPermissionsResult(int requestCode, String[] permissions,
    // int[] grantResults)
    // to handle the case where the user grants the permission. See the documentation
    // for ActivityCompat#requestPermissions for more details.
    return
    }
    tempList.add(ListItem(it.name, it.address))
    }
    adapter.submitList(tempList)
    }

    1. У меня тоже так было(и всё ещё так). Просто проигнорь его и запускай. Кажется код уже написан включая это условие или это просто ненужная проверка которая никак не повлияет на работу приложения.

Добавить комментарий для Андрей Отменить ответ

Ваш адрес email не будет опубликован.