微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Android Studio 上的 Fragment 中扫描 BLE 设备 - Kotlin

如何解决在 Android Studio 上的 Fragment 中扫描 BLE 设备 - Kotlin

几天以来,我试图在我的应用中实现 BLE 连接。我在另一个片段而不是主要片段中这样做。但是当我扫描以找到 BLE 设备(使用 startScan(leScanCallback))时,它永远不会进入回调方法 leScanCallback。我遵循了一些教程,但我不知道为什么它不起作用。

这是我的 MainActivity.kt

package com.example.start

import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.database.DatabaseUtils
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.ActivityCompat
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.drawerlayout.widget.DrawerLayout
import androidx.navigation.findNavController
import androidx.navigation.ui.NavigationUI
import com.example.start.databinding.ActivityMainBinding
import java.util.*

class MainActivity : AppCompatActivity() {

    private lateinit var drawerLayout: DrawerLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //setContentView(R.layout.activity_main)
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
        drawerLayout = binding.drawerLayout
        val navController = this.findNavController(R.id.myNavHostFragment)
        NavigationUI.setupActionBarWithNavController(this,navController,drawerLayout)   //link the navigation controller & drawer layout to the app bar
        NavigationUI.setupWithNavController(binding.navView,navController) //allows the user to display the navigation drawer

        //PERMISSION
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            if (ContextCompat.checkSelfPermission(baseContext,Manifest.permission.ACCESS_BACKGROUND_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
                val PERMISSION_CODE = 0 //Should be >= 0
                ActivityCompat.requestPermissions(
                    this,arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),PERMISSION_CODE)
            }
        }

        //==========================Bluetooth Part==========================================
        val REQUEST_ENABLE_BT : Int = 1 //Will stock the result of enabling the bluetooth
                                        //RESULT_OK =  -1 (0xffffffff)
                                        //RESULT_CANCELLED = 0 (0x00000000)
        //val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
        val bluetoothAdapter: BluetoothAdapter by lazy {
            val bluetoothManager = getSystemService(Context.BLUetoOTH_SERVICE) as BluetoothManager
            bluetoothManager.adapter
        }
        if (bluetoothAdapter == null) {
            // Device doesn't support Bluetooth
        }
        if (bluetoothAdapter?.isEnabled == false) { //If bluetooth is disable,we active it
            val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT)
        }
    }
}

这是我的 ConnectFragment.kt,我按下按钮“btnScan”开始研究

package com.example.start

import android.Manifest
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.companion.AssociationRequest
import android.companion.BluetoothLeDeviceFilter
import android.companion.CompanionDeviceManager
import android.content.Context
import android.content.Intent
import android.content.IntentSender
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.*
import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.getSystemService
import androidx.core.content.PermissionChecker
import androidx.databinding.DataBindingUtil
import androidx.databinding.DataBindingUtil.setContentView
import androidx.fragment.app.Fragment
import com.example.start.databinding.FragmentConnectBinding
import java.util.*

// Todo: Rename parameter arguments,choose names that match
// the fragment initialization parameters,e.g. ARG_ITEM_NUMBER
private const val SELECT_DEVICE_REQUEST_CODE = 0

class ConnectFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        //return inflater.inflate(R.layout.fragment_connect,container,false)
        val binding = DataBindingUtil.inflate<FragmentConnectBinding>(
                inflater,R.layout.fragment_connect,false
        )
        binding.btnScan.setonClickListener {
            view : View ->
            scanLeDevice()
        }
        return binding.root
    }

    private val bluetoothLeScanner: BluetoothLeScanner
        get() {
            val bluetoothManager = requireContext().getSystemService(Context.BLUetoOTH_SERVICE) as BluetoothManager
            val bluetoothAdapter = bluetoothManager.adapter
            return bluetoothAdapter.bluetoothLeScanner
        }
    // Device scan callback.
    private val leScanCallback = object : ScanCallback() {
        override fun onScanResult(callbackType: Int,result: ScanResult) {
            super.onScanResult(callbackType,result)
            //Todo TEST TEST TEST
            Log.d("ScanDeviceActivity","leScanCallback >>")
            Log.d("ScanDeviceActivity","onScanResult(): ${result?.device?.address} - ${result?.device?.name}")
        }
        override fun onBatchScanResults(results: MutableList<ScanResult>?) {
            super.onBatchScanResults(results)
            Log.d("DeviceListActivity","onBatchScanResults:${results.toString()}")
        }

        override fun onScanFailed(errorCode: Int) {
            super.onScanFailed(errorCode)
            Log.d("DeviceListActivity","onScanFailed: $errorCode")
        }
    }
    private var scanning = false
    private val handler = Handler()
    // Stops scanning after 10 seconds.
    private val SCAN_PERIOD: Long = 10000

    fun scanLeDevice() {
 //       val bluetoothManager = context?.getSystemService(Context.BLUetoOTH_SERVICE) as BluetoothManager
 //       val bluetoothAdapter = bluetoothManager.adapter
 //       val bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner
        if (!scanning) { // Stops scanning after a pre-defined scan period.
            handler.postDelayed({
                scanning = false
                bluetoothLeScanner.stopScan(leScanCallback)
            },SCAN_PERIOD)
            scanning = true
            //PERMISSION COARSE LOCATION
            Log.d("ScanDeviceStart","startScan()")
            when (PermissionChecker.checkSelfPermission(requireContext(),Manifest.permission.ACCESS_COARSE_LOCATION)) {
                PackageManager.PERMISSION_GRANTED -> bluetoothLeScanner.startScan(leScanCallback)
                else -> requestPermissions(arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION),1)
            }
        } else {
            scanning = false
            bluetoothLeScanner.stopScan(leScanCallback)
        }
    }

    //Permission
    override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<out String>,grantResults: IntArray) {
        when (requestCode) {
            1 -> when (grantResults) {
                intArrayOf(PackageManager.PERMISSION_GRANTED) -> {
                    Log.d("ScanDevices","onRequestPermissionsResult(PERMISSION_GRANTED)")
                    bluetoothLeScanner.startScan(leScanCallback)
                }
                else -> {
                    Log.d("ScanDevices","onRequestPermissionsResult(not PERMISSION_GRANTED)")
                }
            }
            else -> super.onRequestPermissionsResult(requestCode,permissions,grantResults)
        }
    }
}

按下按钮后,调试的控制台以: D/BluetoothLeScanner:通过回调停止扫描

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。