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>
Здравствуйте. У меня проблема в данной частью кода:
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)
}
У меня тоже так было(и всё ещё так). Просто проигнорь его и запускай. Кажется код уже написан включая это условие или это просто ненужная проверка которая никак не повлияет на работу приложения.