亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android12?藍(lán)牙適配的實(shí)現(xiàn)步驟

 更新時(shí)間:2022年04月27日 15:20:48   作者:初學(xué)者-Study  
本文主要介紹了Android12?藍(lán)牙適配的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在我的申請下,公司終于購買了一臺基于Android12.0的手機(jī),然后我就開心的拿去安裝測試了,發(fā)現(xiàn)程序崩潰了,于是我這里就寫下來,Android12.0的藍(lán)牙適配方法。

在這里插入圖片描述

在Android系統(tǒng)版本中,藍(lán)牙的變化有,但是不多,這里簡要說明一下。

一、Android版本中藍(lán)牙簡介

  • Android1.5 中增加了藍(lán)牙功能,立體聲 Bluetooth 支持:A2DP [Advanced Audio Distribution Profile]、AVCRP [Audio/Video Remote Control Profile],自動(dòng)配對。
  • Android2.0 中支持Bluetooth2.1協(xié)議。
  • Android3.0 中能讓應(yīng)用查詢已經(jīng)連接上 Bluetooth 設(shè)備的 Bluetooth Profile、音頻狀態(tài)等,然后通知用戶。
  • Android3.1 中系統(tǒng)可以通過 Bluetooth HID 方式同時(shí)接入一到多款輸入設(shè)備。
  • Android4.0 中新增支持連接 Bluetooth HDP [Health Device Profile)] 設(shè)備,通過第三方應(yīng)用的支持,用戶可以連接到醫(yī)院、健身中心或者家庭等場合中的無線醫(yī)療設(shè)備和傳感器。
  • Android4.2 中引入了一種新的針對 Android 設(shè)備優(yōu)化的 Bluetooth 協(xié)議棧 BlueDroid,從而取代 BlueZ 協(xié)議棧。Bluedroid 協(xié)議棧由 Google 和 Broadcom 公司共同開發(fā),相對于 BlueZ 協(xié)議棧,BlueDroid 提升了兼容性和可靠性。
  • Android4.3 中增加了對低功耗藍(lán)牙的支持,內(nèi)置支持 Bluetooth AVRCP 1.3,基于 Google 和 Broadcom 公司功能研發(fā)的針對于 Android 設(shè)備優(yōu)化的新的藍(lán)牙協(xié)議棧 BlueDroid。
  • Android4.4 中新增兩種新 Proifle 支持:HID [Human Interface Device]、MAP [Message Access Profile]
  • Android5.0 中支持Bluetooth4.1協(xié)議。
  • Android6.0 中掃描藍(lán)牙需要?jiǎng)討B(tài)獲取定位才行。
  • Android7.0 中支持Bluetooth4.2協(xié)議。
  • Android8.0 中支持Bluetooth5.0協(xié)議,強(qiáng)化了藍(lán)牙音頻的表現(xiàn)。比如編碼/傳輸格式可選SBC、AAC、aptX/aptX HD、LDAC等四種,音質(zhì)依次提高。
  • Android10.0 中支持Bluetooth5.1協(xié)議,在5.0的基礎(chǔ)上,增加了側(cè)向功能和厘米級定位服務(wù),大幅度提高了定位精度。使室內(nèi)定位更精準(zhǔn)。
  • Android11.0 中支持Bluetooth5.2協(xié)議,增強(qiáng)版ATT協(xié)議,LE功耗控制和信號同步,連接更快,更穩(wěn)定,抗干擾性更好。
  • Android12.0 中支持Bluetooth5.3協(xié)議,增強(qiáng)了經(jīng)典藍(lán)牙BR/EDR(基礎(chǔ)速率和增強(qiáng)速率)的安全性。藍(lán)牙5.3的延遲更低、抗干擾性更強(qiáng)、提升了電池續(xù)航時(shí)間。系統(tǒng)引入了新的運(yùn)行時(shí)權(quán)限 BLUETOOTH_SCAN、BLUETOOTH_ADVERTISE 和 BLUETOOTH_CONNECT權(quán)限,用于更好地管理應(yīng)用于附近藍(lán)牙設(shè)備的連接。

二、新建項(xiàng)目

在Android12.0中新增加了三個(gè)運(yùn)行時(shí)權(quán)限,我們依次來說明一下,這里我們依然創(chuàng)建一個(gè)項(xiàng)目來說明,新建一個(gè)Android12Bluetooth項(xiàng)目,如下圖所示:

在這里插入圖片描述

這里使用Kotlin來寫,點(diǎn)擊Finish。

① 配置settings.gradle和build.gradle

然后來配置一下項(xiàng)目的依賴庫,首先是在工程的settings.gradle中增加如下依賴:

maven { url "https://jitpack.io" }

增加位置如下圖所示:

在這里插入圖片描述

然后在app的build.gradle中增加

	buildFeatures {
        viewBinding true
        dataBinding true
    }

	implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'

增加位置如下圖所示:

在這里插入圖片描述

然后Sync Now。

② 配置AndroidManifest.xml

下面配置AndroidMainfest.xml,權(quán)限如下所示:

	<uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <!--Android12 的藍(lán)牙權(quán)限 如果您的應(yīng)用與已配對的藍(lán)牙設(shè)備通信或者獲取當(dāng)前手機(jī)藍(lán)牙是否打開-->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
    <!--Android12 的藍(lán)牙權(quán)限 如果您的應(yīng)用查找藍(lán)牙設(shè)備(如藍(lán)牙低功耗 (BLE) 外圍設(shè)備)-->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
    <!--Android12 的藍(lán)牙權(quán)限 如果您的應(yīng)用使當(dāng)前設(shè)備可被其他藍(lán)牙設(shè)備檢測到-->
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>

增加位置如下圖所示:

在這里插入圖片描述

三、打開藍(lán)牙

下面我們構(gòu)建一下activity_main.xml中的代碼:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <Button
        android:id="@+id/btn_open_bluetooth"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:insetTop="0dp"
        android:insetBottom="0dp"
        android:text="打開藍(lán)牙"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

這里就是寫一個(gè)按鈕,用來點(diǎn)擊打開系統(tǒng)藍(lán)牙的開關(guān)的。在Android12.0之前打開藍(lán)牙的之前需要先判斷藍(lán)牙是否打開,我們可以這樣來寫,在MainActivity中增加如下代碼:

	private fun isOpenBluetooth(): Boolean {
        val manager = getSystemService(BLUETOOTH_SERVICE) as BluetoothManager
        val adapter = manager.adapter ?: return false
        return adapter.isEnabled
    }

同樣我們還需要一個(gè)方法判斷當(dāng)前是否為Android12及以上版本。

private fun isAndroid12() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S

同樣還有一個(gè)檢查此權(quán)限是否授予的方法和一個(gè)顯示Toast的方法:

	private fun hasPermission(permission: String) =
        checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED

    private fun showMsg(msg: String) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
    }

① 打開藍(lán)牙意圖

在MainActivity中新增如下代碼:

	//打開藍(lán)牙意圖
    val enableBluetooth = registerForActivityResult(StartActivityForResult()) {
        if (it.resultCode == Activity.RESULT_OK) {
            showMsg(if (isOpenBluetooth()) "藍(lán)牙已打開" else "藍(lán)牙未打開")
        }
    }

此方法就替代了之前startActivityForResult,現(xiàn)在我們使用registerForActivityResult。再返回中可以得知當(dāng)前是否打開了藍(lán)牙。

② 請求BLUETOOTH_CONNECT權(quán)限意圖

registerForActivityResult不光能用于頁面獲取值,也能用于請求權(quán)限。

	//請求BLUETOOTH_CONNECT權(quán)限意圖
    val requestBluetoothConnect = registerForActivityResult(ActivityResultContracts.RequestPermission()) {
            if (it) {
                //打開藍(lán)牙
                enableBluetooth.launch(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
            } else {
                showMsg("Android12中未獲取此權(quán)限,則無法打開藍(lán)牙。")
            }
        }

請求權(quán)限返回?zé)o非就是同意不同意,如果同意了我們就調(diào)用

enableBluetooth.launch(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))

去打開系統(tǒng)藍(lán)牙,不同意就提示一下。下面再用ViewBinding來配置一下:

在這里插入圖片描述

這里有一個(gè)initView的函數(shù),在這個(gè)函數(shù)中我們對按鈕的點(diǎn)擊事件進(jìn)行操作,新增initView()函數(shù),代碼如下:

	private fun initView() {
        binding.btnOpenBluetooth.setOnClickListener {
            //藍(lán)牙是否已打開
            if (isOpenBluetooth()){
                showMsg("藍(lán)牙已打開")
                return@setOnClickListener
            }
            //是Android12
            if (isAndroid12()) {
                //檢查是否有BLUETOOTH_CONNECT權(quán)限
                if (hasPermission(Manifest.permission.BLUETOOTH_CONNECT)) {
                    //打開藍(lán)牙
                    enableBluetooth.launch(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
                } else {
                    //請求權(quán)限
                    requestBluetoothConnect.launch(Manifest.permission.BLUETOOTH_CONNECT)
                }
                return@setOnClickListener
            }
            //不是Android12 直接打開藍(lán)牙
            enableBluetooth.launch(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
        }
    }

這里的代碼就比較好理解,首先判斷藍(lán)牙是否已經(jīng)打開了,打開了就不往下執(zhí)行,沒打開,再判斷當(dāng)前是否為Android12,不是就直接打開系統(tǒng)藍(lán)牙,是Android12,再去檢查是否授予BLUETOOTH_CONNECT權(quán)限,授予了就打開系統(tǒng)藍(lán)牙,沒有授予就去請求此權(quán)限,下面我們運(yùn)行一下:

在這里插入圖片描述

四、藍(lán)牙掃描

在Android6.0 - Android11.0之間,掃描藍(lán)牙都是需要打開定位權(quán)限的,而在Android12中則不需要了,換成了BLUETOOTH_SCAN權(quán)限,那么我們下面來看看,怎么操作的。

這里掃描藍(lán)牙就以低功耗藍(lán)牙為例子。

① 掃描者

在MainActivity中定義如下變量

	private val TAG = MainActivity::class.java.simpleName

    //獲取系統(tǒng)藍(lán)牙適配器
    private lateinit var mBluetoothAdapter: BluetoothAdapter

    //掃描者
    private lateinit var scanner: BluetoothLeScanner

    //是否正在掃描
    var isScanning = false

獲取系統(tǒng)藍(lán)牙適配器,要在onCreate回調(diào)中,如下圖所示:

在這里插入圖片描述

② 掃描回調(diào)

掃描設(shè)備時(shí)會(huì)有掃描的結(jié)果,在MainActivity中增加如下代碼:

	//掃描結(jié)果回調(diào)
    private val scanCallback = object : ScanCallback() {
        override fun onScanResult(callbackType: Int, result: ScanResult) {
            val device = result.device
            Log.d(TAG, "name: ${device.name}, address: ${device.address}")
        }
    }

這里可能你的device.name下面會(huì)有一個(gè)紅線,這是因?yàn)锳S會(huì)檢查你這里需要一個(gè)BLUETOOTH_CONNECT權(quán)限,而這個(gè)權(quán)限我們在打開藍(lán)牙時(shí)已經(jīng)請求過了,那么為了避免麻煩,我們在當(dāng)前MainActivity上面增加如下注解。

@SuppressLint("MissingPermission")

如下圖所示:

在這里插入圖片描述

這個(gè)注解加上去之后你需要小心藍(lán)牙權(quán)限的問題。

③ 掃描方法

下面我們寫一個(gè)開始掃描和停止掃描的方法,代碼如下:

	private fun startScan() {
        if (!isScanning) {
            scanner.startScan(scanCallback)
            isScanning = true
            binding.btnScanBluetooth.text = "停止掃描"
        }
    }

    private fun stopScan() {
        if (isScanning) {
            scanner.stopScan(scanCallback)
            isScanning = false
            binding.btnScanBluetooth.text = "掃描藍(lán)牙"
        }
    }

掃描和停止掃描時(shí)修改一下變量值并且改動(dòng)按鈕的文字以表示當(dāng)前是否正在掃描中。

④ 執(zhí)行掃描

執(zhí)行掃描就很簡單了,首先我們需要在MainActivity中創(chuàng)建掃描意圖:

	//請求BLUETOOTH_SCAN權(quán)限意圖
    private val requestBluetoothScan =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) {
            if (it) {
                //進(jìn)行掃描
                startScan()
            } else {
                showMsg("Android12中未獲取此權(quán)限,則無法掃描藍(lán)牙。")
            }
        }

這個(gè)意圖我們將在點(diǎn)擊掃描按鈕的時(shí)候會(huì)用到,下面我們在initView中增加掃描按鈕點(diǎn)擊的代碼:

		//掃描藍(lán)牙
        binding.btnScanBluetooth.setOnClickListener {
            if (isAndroid12()) {
                if (hasPermission(Manifest.permission.BLUETOOTH_SCAN)) {
                    //掃描或者停止掃描
                    if (isScanning) stopScan() else startScan()
                } else {
                    //請求權(quán)限
                    requestBluetoothScan.launch(Manifest.permission.BLUETOOTH_SCAN)
                }
            }
        }

相對來說還是比較的簡潔,其實(shí)還可以更簡潔。我在掃描回調(diào)中打印了日志,如果有掃描到設(shè)備的話,就會(huì)有日志,下面我們掃描一下看看:

在這里插入圖片描述

掃描啟動(dòng)了,但是沒有設(shè)備被掃描到,可我附近明明有藍(lán)牙設(shè)備正在廣播,這是為什么呢?

⑤ 應(yīng)用不推導(dǎo)物理位置

這個(gè)說起來就和之前的Android 6.0 至 Android 11.0中需要定位權(quán)限才能掃描有關(guān)系了,就是因?yàn)檫@個(gè)推導(dǎo)物理位置,手機(jī)是可以通過掃描到的設(shè)備知道設(shè)備的具體位置的,所以之前需要定位權(quán)限,那么現(xiàn)在我沒有定位權(quán)限了,你掃不到設(shè)備就很離譜,怎么解決呢?

如果您的應(yīng)用不推導(dǎo)物理位置,那么您可以堅(jiān)定地?cái)嘌阅膽?yīng)用絕不會(huì)使用藍(lán)牙權(quán)限來推導(dǎo)物理位置。為此,請完成以下步驟:

將 android:usesPermissionFlags 屬性添加到 BLUETOOTH_SCAN 權(quán)限聲明,并將此屬性的值設(shè)為 neverForLocation。

注意:如果 android:usesPermissionFlags 中包含 neverForLocation,則會(huì)從掃描結(jié)果中過濾出某些 BLE 信標(biāo)。

這是官方的說明,操作起來很簡單,如下圖所示:

在這里插入圖片描述

意思很明顯,就是說你如果不需要推導(dǎo)物理地址,那么就設(shè)置一下這個(gè)權(quán)限的標(biāo)識即可。下面我們再來運(yùn)行一下:

在這里插入圖片描述

設(shè)備就掃描到了,可以看到這里有設(shè)備的Mac地址,再點(diǎn)一下就可以停止掃描了。

不過我們這里是控制臺顯示了設(shè)備,并沒有在頁面顯示設(shè)備,下面我們完成這一步。

五、頁面顯示掃描設(shè)備

顯示藍(lán)牙設(shè)備首先我們需要修改一下activity_main.xml布局,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btn_open_bluetooth"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:insetTop="0dp"
        android:insetBottom="0dp"
        android:text="打開藍(lán)牙"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_scan_bluetooth"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="20dp"
        android:layout_marginEnd="10dp"
        android:insetTop="0dp"
        android:insetBottom="0dp"
        android:text="掃描藍(lán)牙"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_open_bluetooth" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_device"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="20dp"
        android:overScrollMode="never"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btn_scan_bluetooth" />

</androidx.constraintlayout.widget.ConstraintLayout>

① 藍(lán)牙設(shè)備適配器

這個(gè)里的適配器使我們自己去寫的,需要顯示數(shù)據(jù)的,首先我們需要?jiǎng)?chuàng)建一個(gè)藍(lán)牙圖標(biāo),在drawable包下新建一個(gè)icon_bluetooth.xml,里面的代碼如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="48dp"
    android:height="48dp"
    android:autoMirrored="true"
    android:tint="#000000"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">

    <path
        android:fillColor="@android:color/white"
        android:pathData="M14.24,12.01l2.32,2.32c0.28,-0.72 0.44,-1.51 0.44,-2.33 0,-0.82 -0.16,-1.59 -0.43,-2.31l-2.33,2.32zM19.53,6.71l-1.26,1.26c0.63,1.21 0.98,2.57 0.98,4.02s-0.36,2.82 -0.98,4.02l1.2,1.2c0.97,-1.54 1.54,-3.36 1.54,-5.31 -0.01,-1.89 -0.55,-3.67 -1.48,-5.19zM15.71,7.71L10,2L9,2v7.59L4.41,5 3,6.41 8.59,12 3,17.59 4.41,19 9,14.41L9,22h1l5.71,-5.71 -4.3,-4.29 4.3,-4.29zM11,5.83l1.88,1.88L11,9.59L11,5.83zM12.88,16.29L11,18.17v-3.76l1.88,1.88z" />

</vector>

因?yàn)槲覀兊脑O(shè)備需要顯示信號強(qiáng)度,那么我們創(chuàng)建一個(gè)數(shù)據(jù)類,在com.llw.bluetooth包下新建一個(gè)MyDevice類,代碼如下:

data class MyDevice(val device: BluetoothDevice, var rssi: Int)

然后我們構(gòu)建適配器的item布局,在layout包下新建一個(gè)item_device.xml,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="device"
            type="com.llw.bluetooth.MyDevice" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="70dp">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginStart="10dp"
            android:layout_marginTop="10dp"
            android:padding="8dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/icon_bluetooth" />

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginTop="4dp"
            android:layout_marginEnd="10dp"
            android:text="@{device.device.name ?? `Unknown` }"
            android:textColor="@color/black"
            android:textSize="14sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toStartOf="@+id/tv_rssi"
            app:layout_constraintStart_toEndOf="@+id/imageView"
            app:layout_constraintTop_toTopOf="@+id/imageView" />

        <TextView
            android:id="@+id/tv_address"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:layout_marginBottom="4dp"
            android:text="@{device.device.address}"
            android:textSize="12sp"
            app:layout_constraintBottom_toBottomOf="@+id/imageView"
            app:layout_constraintEnd_toStartOf="@+id/tv_rssi"
            app:layout_constraintStart_toEndOf="@+id/imageView" />

        <TextView
            android:id="@+id/tv_rssi"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="10dp"
            android:text="@{device.rssi+`dBm`}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

這里的布局?jǐn)?shù)據(jù)采用了DataBinding。下面我們?nèi)戇m配器,在com.llw.bluetooth包新建一個(gè)MyDeviceAdapter類,里面的代碼如下:

class MyDeviceAdapter(data: MutableList<MyDevice>) :
    BaseQuickAdapter<MyDevice, BaseDataBindingHolder<ItemDeviceBinding>>(R.layout.item_device, data) {
    override fun convert(holder: BaseDataBindingHolder<ItemDeviceBinding>, item: MyDevice) {
        holder.dataBinding?.apply {
            device = item
            executePendingBindings()
        }
    }
}

這里就用到之前build.gradle中第三方依賴庫的適配器,相當(dāng)好用。下面我們回到MainActivity中。

② 顯示列表設(shè)備

在MainActivity中創(chuàng)建兩個(gè)變量:

	//設(shè)備列表
    private val deviceList = mutableListOf<MyDevice>()
    //適配器
    private lateinit var myDeviceAdapter: MyDeviceAdapter

這里我們需要思考一個(gè)問題,那就是列表設(shè)備的唯一性,因?yàn)樗{(lán)牙設(shè)備是一直廣播的,所以我們掃描到的結(jié)果會(huì)有重復(fù)的設(shè)備,重復(fù)的設(shè)備有信號強(qiáng)度上的差異,這個(gè)地方我們要做的就是判斷當(dāng)前列表中是否有此設(shè)備,有就更新rssi,沒有就添加,我們新增一個(gè)findDeviceIndex()函數(shù),代碼如下:

	private fun findDeviceIndex(scanDevice: MyDevice, deviceList: List<MyDevice>): Int {
        var index = 0
        for (device in deviceList) {
            if (scanDevice.device.address.equals(device.device.address)) return index
            index += 1
        }
        return -1
    }

下面我們再新增一個(gè)addDeviceList()函數(shù),代碼如下:

	private fun findDeviceIndex(scanDevice: MyDevice, deviceList: List<MyDevice>): Int {
        var index = 0
        for (device in deviceList) {
            if (scanDevice.device.address.equals(device.device.address)) return index
            index += 1
        }
        return -1
    }

最后我們在掃描回調(diào)中調(diào)用此方法:

在這里插入圖片描述

最后別忘記了我們的適配器和列表都需要初始化的,我寫在initView()函數(shù)中,如下圖所示:

在這里插入圖片描述

現(xiàn)在就可以運(yùn)行了。

在這里插入圖片描述

其實(shí)Android12藍(lán)牙只有權(quán)限上要注意一下,雖然有三個(gè)動(dòng)態(tài)權(quán)限,但是只要你同意了一個(gè)就都同意了,因?yàn)樗鼈儗儆谕粋€(gè)權(quán)限組,所以如果你能確保當(dāng)前擁有其中一個(gè)權(quán)限的話,藍(lán)牙的操作就和之前一樣的。不過還是有一些問題的,那就是在打開藍(lán)牙之后要對變量進(jìn)行賦值,如下圖所示:

在這里插入圖片描述

六、適配Android12.0以下設(shè)備

當(dāng)前的代碼我們在Android12上是沒有問題了,但是Android12一下Android6.0以上還是掃描不到設(shè)備,因?yàn)樾枰ㄎ粰?quán)限,那么我們在AndroidManifest.xml中增加:

	<!--Android6-11 定位權(quán)限-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

然后我們回到MainActivity中,增加一個(gè)定位意圖

	//請求定位權(quán)限意圖
    private val requestLocation =
        registerForActivityResult(ActivityResultContracts.RequestPermission()) {
            if (it) {
                //掃描藍(lán)牙
                startScan()
            } else {
                showMsg("Android12以下,6及以上需要定位權(quán)限才能掃描設(shè)備")
            }
        }

然后我們回到掃描按鈕的點(diǎn)擊事件。

在這里插入圖片描述

下面我們在Android10.0上運(yùn)行一下:

在這里插入圖片描述

七、源碼

如果你覺得代碼對你有幫助的話,不妨Fork或者Star一下~
GitHub:Android12Bluetooth

到此這篇關(guān)于Android12 藍(lán)牙適配的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)Android12 藍(lán)牙適配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論