如何使用 kotlin 扫描蓝牙设备
How to scan for bluetooth devices with kotlin
我正在用 kotlin 编写 android 应用程序,我想扫描附近的蓝牙设备,不是 之前配对的设备,我是 不 使用 BLE。
到目前为止,我已尝试使用蓝牙适配器的函数 startDiscovery(),该函数可能会开始发现设备,但没有任何反应。根据 developer.android.com 它应该扫描 12 秒。在我的代码中,它在启动后立即停止。下面的代码是我到目前为止所拥有的。我会把recycleView adapter也放上去,方便大家测试app。
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)
}
主要Activity
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) and here (bluetooth)。请注意,link 中的初始蓝牙代码设置为查找先前配对的设备。那部分对我来说很管用,但这不是我想要的。
抱歉拖了这么久 post 如果您需要更多信息,请在评论中告诉我,我也会添加。提前致谢。
尝试在getDefaultAdapter()
之前使用startDiscovery()
方法,甚至enable()
方法。
有关更多信息,请查看:BluetoothAdapter
您在开始发现时注销了接收器。
将此:unregisterReceiver(Received) 移至 onStop
并将 registerReceiver 到 onStart
我正在用 kotlin 编写 android 应用程序,我想扫描附近的蓝牙设备,不是 之前配对的设备,我是 不 使用 BLE。
到目前为止,我已尝试使用蓝牙适配器的函数 startDiscovery(),该函数可能会开始发现设备,但没有任何反应。根据 developer.android.com 它应该扫描 12 秒。在我的代码中,它在启动后立即停止。下面的代码是我到目前为止所拥有的。我会把recycleView adapter也放上去,方便大家测试app。
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)
}
主要Activity
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) and here (bluetooth)。请注意,link 中的初始蓝牙代码设置为查找先前配对的设备。那部分对我来说很管用,但这不是我想要的。
抱歉拖了这么久 post 如果您需要更多信息,请在评论中告诉我,我也会添加。提前致谢。
尝试在getDefaultAdapter()
之前使用startDiscovery()
方法,甚至enable()
方法。
有关更多信息,请查看:BluetoothAdapter
您在开始发现时注销了接收器。 将此:unregisterReceiver(Received) 移至 onStop 并将 registerReceiver 到 onStart