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 не будет опубликован.