【发布时间】:2020-07-29 16:25:09
【问题描述】:
我正在用 kotlin 编写一个 android 应用程序,我想扫描附近的蓝牙设备和 NOT 以前配对的设备,我NOT 使用 BLE。
到目前为止,我已尝试使用蓝牙适配器的函数 startDiscovery(),该函数可能会开始发现设备,但没有任何反应。根据developer.android.com,它应该扫描 12 秒。在我的代码中,它在启动后立即停止。下面的代码是我到目前为止所拥有的。我会把recycleView适配器也放上来,方便大家测试应用。
RecycleView 适配器
package com.example.andruino_bt
import android.bluetooth.BluetoothDevice
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.View
import android.view.ViewGroup
import kotlinx.android.synthetic.main.activity_main_recycle_view.view.*
class RecyclerAdapter(private val devices: ArrayList<BluetoothDevice>) : RecyclerView.Adapter<RecyclerAdapter.DeviceHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DeviceHolder {
val inflatedView = parent.inflate(R.layout.activity_main_recycle_view, false)
return DeviceHolder(inflatedView)
}
override fun getItemCount(): Int {
Log.i("", devices.size.toString())
return devices.size
}
override fun onBindViewHolder(holder: DeviceHolder, position: Int) {
val itemDevice = devices[position]
holder.bindDevice(itemDevice)
}
class DeviceHolder(v: View) : RecyclerView.ViewHolder(v), View.OnClickListener {
private var view: View = v
private var device : BluetoothDevice? = null
init {
v.setOnClickListener(this)
}
override fun onClick(v: View) {
Log.i("RecyclerView", "CLICK!")
}
fun bindDevice(device: BluetoothDevice) {
this.device = device
val name = "Name: ${device.name}"
view.device_name.text = name
val address = "Address: ${device.address}"
view.device_add.text = address
Log.i("RecyclerView", device.name.toString())
}
companion object {
private val PHOTO_KEY = "PHOTO"
}
}
}
膨胀函数(在单独的文件中)
package com.example.andruino_bt
import android.support.annotation.LayoutRes
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): View {
return LayoutInflater.from(context).inflate(layoutRes, this, attachToRoot)
}
主要活动
package com.example.andruino_bt
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.util.Log
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
import android.support.v4.widget.SwipeRefreshLayout
class MainActivity : AppCompatActivity(){
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var m_pairedDevices: Set<BluetoothDevice>
private lateinit var adapter: RecyclerAdapter
private var m_bluetoothAdapter: BluetoothAdapter? = null
private val REQUEST_ENABLE_BLUETOOTH = 1
private val devices_list : ArrayList<BluetoothDevice> = ArrayList()
private val swipeContainer: SwipeRefreshLayout? = null
companion object {
val EXTRA_ADDRESS: String = "Device_address"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar?.hide()
m_bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if(m_bluetoothAdapter == null) {
Toast.makeText(this, "this device doesn't support bluetooth", Toast.LENGTH_SHORT).show()
return
}
if(!m_bluetoothAdapter!!.isEnabled) {
val enableBluetoothIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableBluetoothIntent, REQUEST_ENABLE_BLUETOOTH)
val discoverableIntent: Intent = Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE).apply {
putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300)
}
startActivity(discoverableIntent)
}else{
discoverDevices()
}
findViewById<SwipeRefreshLayout>(R.id.swipeContainer).setOnRefreshListener{
devices_list.clear()
discoverDevices()
}
}
private val mReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (BluetoothDevice.ACTION_FOUND == action) {
// A Bluetooth device was found
// Getting device information from the intent
val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
devices_list.add(device)
}
}
}
private fun discoverDevices(){
if (m_bluetoothAdapter!!.isDiscovering) {
// Bluetooth is already in mode discovery mode, we cancel to restart it again
m_bluetoothAdapter!!.cancelDiscovery()
}
val bool = m_bluetoothAdapter?.startDiscovery()
Log.i("", bool.toString())
val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
registerReceiver(mReceiver, filter)
linearLayoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = linearLayoutManager
adapter = RecyclerAdapter(devices_list)
recyclerView.adapter = adapter
findViewById<SwipeRefreshLayout>(R.id.swipeContainer).isRefreshing = false
unregisterReceiver(mReceiver)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_ENABLE_BLUETOOTH) {
if (resultCode == Activity.RESULT_OK) {
if (m_bluetoothAdapter!!.isEnabled) {
Toast.makeText(this, "Bluetooth enabled", Toast.LENGTH_SHORT).show()
discoverDevices()
} else {
Toast.makeText(this, "Bluetooth disabled", Toast.LENGTH_SHORT).show()
}
} else if (resultCode == Activity.RESULT_CANCELED) {
Toast.makeText(this, "Bluetooth enabling has been canceled", Toast.LENGTH_SHORT).show()
}
}
}
}
作为布局,我在 swipeContainer 中使用 RecycleView 进行刷新。同样在清单中,我具有以下权限:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
代码的最大部分被发现here (recycleView)和here (bluetooth)。请注意,链接中的初始蓝牙代码设置为查找以前配对的设备。那部分对我来说效果很好,但这不是我想要的。
抱歉,这篇文章很长,如果您需要更多信息,请在评论中告诉我,所以我也会添加。提前致谢。
【问题讨论】:
标签: android kotlin bluetooth android-bluetooth