国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android Ble藍(lán)牙App(二)連接與發(fā)現(xiàn)服務(wù)

這篇具有很好參考價(jià)值的文章主要介紹了Android Ble藍(lán)牙App(二)連接與發(fā)現(xiàn)服務(wù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言

??在上一篇中我們進(jìn)行掃描設(shè)備的處理,本文中進(jìn)行連接和發(fā)現(xiàn)服務(wù)的數(shù)據(jù)處理,運(yùn)行效果圖如下所示:
android ble藍(lán)牙調(diào)用 ui線程,藍(lán)牙,BLE連接設(shè)備,BLE發(fā)現(xiàn)服務(wù)

目錄

  • Ble藍(lán)牙App(一)掃描
  • Ble藍(lán)牙App(二)連接與發(fā)現(xiàn)服務(wù)
  • Ble藍(lán)牙App(三)特性和屬性
  • Ble藍(lán)牙App(四)UI優(yōu)化和描述符
  • Ble藍(lán)牙App(五)數(shù)據(jù)操作

正文

??現(xiàn)在我們從MainActivity進(jìn)入到ScanActivity,選中一個(gè)設(shè)備返回到MainActivity,下面要對(duì)選中的設(shè)備進(jìn)行處理,首先我們來(lái)做連接。

一、GATT回調(diào)

??在之前我們寫(xiě)了一個(gè)BleCore,這里面是對(duì)掃描的封裝,那么對(duì)于連接來(lái)說(shuō)我們同樣可以封裝到這里,我們可以在BleCore中寫(xiě)一個(gè)BleGattCallback 類(lèi),代碼如下所示:

class BleGattCallback : BluetoothGattCallback() {

        /**
         * 連接狀態(tài)改變
         */
        override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
            
        }

        /**
         * 發(fā)現(xiàn)服務(wù)
         */
        override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
            
        }
    }

??因?yàn)楸疚囊龅氖虑槭沁B接和發(fā)現(xiàn)服務(wù),所以我們就先重寫(xiě)這兩個(gè)函數(shù),注意一點(diǎn)的是,藍(lán)牙的操作都是在子線程中進(jìn)行的,如果我們需要知道當(dāng)前是否連接,則需要寫(xiě)一個(gè)接口用于回調(diào)到Activity中,在ble包下新建一個(gè)BleCallback接口,代碼如下所示:

interface BleCallback {

    /**
     * 設(shè)備的所有信息
     */
    fun deviceInfo(info: String)

    /**
     * 連接狀態(tài)
     * @param state true or false
     */
    fun onConnectionStateChange(state: Boolean)

    /**
     * 發(fā)現(xiàn)服務(wù)
     */
    fun onServicesDiscovered(services: List<BluetoothGattService>)
}

??接口中定義了三個(gè)函數(shù),通過(guò)注釋我們清晰的知道都是什么作用,這里著重介紹第一個(gè)函數(shù),這個(gè)函數(shù)會(huì)顯示設(shè)備各個(gè)時(shí)候的狀態(tài)信息,從連接之后的所有動(dòng)作,如果我們需要保存設(shè)備的操作日志的話,可以通過(guò)這個(gè)來(lái)進(jìn)行處理保存。

然后回到BleCore,在companion object中聲明變量和設(shè)置接口回調(diào)的函數(shù):

    @SuppressLint("StaticFieldLeak")
    companion object {

        ...

        private var mGatt: BluetoothGatt? = null

        private var mBleCallback: BleCallback? = null

        private lateinit var mBleGattCallback: BleGattCallback
        /**
         * 是否連接
         */
        private var mIsConnected = false

        fun getInstance(context: Context) = instance ?: synchronized(this) {
            instance ?: BleCore(context).also {
                instance = it
                //藍(lán)牙掃描
                bleScan = BleScan.getInstance(context)
                //初始化
                mBleGattCallback = BleGattCallback()
            }
        }		

        /**
         * 設(shè)備信息
         */
        private fun deviceInfo(info: String) = mBleCallback?.deviceInfo(info)
        /**
         * 連接狀態(tài)
         */
        private fun connectState(state: Boolean) {
            mIsConnected = state
            mBleCallback?.onConnectionStateChange(state)
        }
    }

同時(shí)在 companion object外創(chuàng)建一個(gè)函數(shù),代碼如下所示:

    fun setBleCallback(bleCallback: BleCallback) {
        mBleCallback = bleCallback
    }

此函數(shù)和setPhyScanCallback()函數(shù)是同級(jí)的,下面我們?cè)黾舆B接和斷連的函數(shù)。

二、連接和斷連

在BleCore中增加如下代碼:

	/**
     * 連接藍(lán)牙設(shè)備
     */
    fun connect(device: BluetoothDevice) {
        deviceInfo("連接中...")
        mGatt = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            device.connectGatt(context, false, mBleGattCallback, BluetoothDevice.TRANSPORT_LE, BluetoothDevice.PHY_LE_2M_MASK)
        } else {
            device.connectGatt(context, false, mBleGattCallback)
        }
    }

    /**
     * 斷開(kāi)連接
     */
    fun disconnect() {
        deviceInfo("斷開(kāi)連接...")
        mGatt?.disconnect()
    }

連接與斷開(kāi)連接,調(diào)用時(shí)會(huì)觸發(fā)onConnectionStateChange()函數(shù)。

三、連接狀態(tài)回調(diào)

下面修改這個(gè)函數(shù)的代碼,如下所示:

        override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
            val address = gatt.device.address
            when (newState) {
                BluetoothProfile.STATE_CONNECTED -> {
                    deviceInfo("已連接:$address")
                    connectState(true)
                }
                BluetoothProfile.STATE_DISCONNECTED -> {
                    deviceInfo("已斷開(kāi)連接:$address")
                    connectState(false)
                }
                else -> {
                    Log.d(TAG, "onConnectionStateChange: $status")
                    connectState(false)
                    mGatt?.close()
                    mGatt = null
                }
            }
        }

在回調(diào)中,連接成功和斷開(kāi)連接都會(huì)有一個(gè)對(duì)應(yīng)的狀態(tài)碼,通過(guò)狀態(tài)回調(diào)到接口函數(shù)中,然后回到MainActivity中使用一下這個(gè)回調(diào),首先我們修改一下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">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/orange"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navigationIcon="@drawable/ic_scan_ble"
        app:title="GoodBle"
        app:titleCentered="true"
        app:titleTextColor="@color/white">

        <TextView
            android:id="@+id/tv_disconnect"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:layout_marginEnd="8dp"
            android:visibility="gone"
            android:padding="8dp"
            android:text="斷開(kāi)連接"
            android:textColor="@color/white" />
    </com.google.android.material.appbar.MaterialToolbar>

    <TextView
        android:id="@+id/tv_device_info"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="設(shè)備信息"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar" />

</androidx.constraintlayout.widget.ConstraintLayout>

在XML中只增加了兩個(gè)TextView,分別用于斷連和顯示設(shè)備狀態(tài),然后我們修改MainActivity中的代碼,如下所示:

class MainActivity : BaseActivity(), BleCallback {

    private val binding by viewBinding(ActivityMainBinding::inflate)

    private lateinit var bleCore: BleCore

    @SuppressLint("MissingPermission")
    private val scanIntent =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            if (result.resultCode == Activity.RESULT_OK) {
                if (result.data == null) return@registerForActivityResult
                //獲取選中的設(shè)備
                val device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                    result.data!!.getParcelableExtra("device", BluetoothDevice::class.java)
                } else {
                    result.data!!.getParcelableExtra("device") as BluetoothDevice?
                }
                //連接設(shè)備
                if (device != null) bleCore.connect(device)
            }
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        bleCore = (application as BleApp).getBleCore()
        bleCore.setBleCallback(this@MainActivity)
        //進(jìn)入掃描頁(yè)面
        binding.toolbar.setNavigationOnClickListener { scanIntent.launch(Intent(this,ScanActivity::class.java)) }
        //斷開(kāi)連接
        binding.tvDisconnect.setOnClickListener {
            binding.tvDisconnect.visibility = View.GONE
            bleCore.disconnect()
        }
    }

    override fun deviceInfo(info: String) {
        runOnUiThread {
            binding.tvDeviceInfo.text = info
        }
    }

    override fun onConnectionStateChange(state: Boolean) {
        runOnUiThread {
            if (state) binding.tvDisconnect.visibility = View.VISIBLE
        }
    }

    override fun onServicesDiscovered(services: List<BluetoothGattService>) {
        
    }
}

??這里我們首先是通過(guò)Activity Result API的StartActivityForResult()函數(shù)進(jìn)行頁(yè)面跳轉(zhuǎn),在返回的時(shí)候拿到device對(duì)象,這在前一篇已經(jīng)寫(xiě)好了,拿到device對(duì)象之后調(diào)用BleCoreconnect()函數(shù)進(jìn)行連接設(shè)備,在onCreate()函數(shù)中進(jìn)行BleCore的賦值,然后設(shè)置Ble的回調(diào),實(shí)現(xiàn)BleCallback接口,重寫(xiě)里面的函數(shù),當(dāng)連接成功之后會(huì)通過(guò)回調(diào)deviceInfo()得到設(shè)備狀態(tài),因?yàn)槭亲泳€程所以在ui線程中渲染UI。而onConnectionStateChange()函數(shù),回調(diào)連接成功或者失敗,如果成功則為ture,就顯示tvDisconnect控件,此時(shí)連接成功,點(diǎn)擊這個(gè)tvDisconnect就會(huì)斷開(kāi)連接,點(diǎn)擊監(jiān)聽(tīng)就在onCreate()中寫(xiě)好了,下面我們運(yùn)行一下看看效果。

android ble藍(lán)牙調(diào)用 ui線程,藍(lán)牙,BLE連接設(shè)備,BLE發(fā)現(xiàn)服務(wù)

從這個(gè)效果圖來(lái)看,我們連接成功之后有狀態(tài),點(diǎn)擊斷開(kāi)連接也會(huì)有狀態(tài)改變,那么連接就寫(xiě)好了。

四、發(fā)現(xiàn)服務(wù)

??連接寫(xiě)好了,下面可以寫(xiě)發(fā)現(xiàn)服務(wù)了,我們可以在連接成功的處理中進(jìn)行發(fā)現(xiàn)服務(wù),下面我們修改一下BleGattCallback中的onConnectionStateChange()函數(shù)中的代碼,如下圖所示:

android ble藍(lán)牙調(diào)用 ui線程,藍(lán)牙,BLE連接設(shè)備,BLE發(fā)現(xiàn)服務(wù)

通過(guò)gatt.discoverServices()進(jìn)行發(fā)現(xiàn)服務(wù)的動(dòng)作,在此之前通過(guò)deviceInfo設(shè)置當(dāng)前的動(dòng)作狀態(tài),發(fā)現(xiàn)服務(wù)執(zhí)行會(huì)觸發(fā)onServicesDiscovered()回調(diào),在這個(gè)回調(diào)中我們可以回調(diào)到頁(yè)面,修改代碼如下所示:

        override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                deviceInfo("發(fā)現(xiàn)了 ${gatt.services.size} 個(gè)服務(wù)")
                gatt.services?.let { mBleCallback?.onServicesDiscovered(it) }
            }
        }

在回調(diào)中設(shè)置發(fā)現(xiàn)服務(wù)的個(gè)數(shù),然后回調(diào),因?yàn)榉?wù)是多個(gè)的,那么下面我們就需要使用一個(gè)列表是裝載服務(wù),首先我們修改一下activity_main.xml,在里面增加一個(gè)RecyclerView,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout...>

    ...

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_service"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_device_info" />

</androidx.constraintlayout.widget.ConstraintLayout>

五、服務(wù)適配器

??要顯示服務(wù)列表數(shù)據(jù),首先需要一個(gè)適配器,而適配器又需要一個(gè)item去渲染數(shù)據(jù),下面我們?cè)趌ayout下創(chuàng)建一個(gè)item_service.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"
    android:id="@+id/item_service"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="2dp"
    android:background="@color/white"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_service_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:text="服務(wù)"
        android:textColor="@color/black"
        android:textSize="16sp"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_uuid_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="UUID:"
        app:layout_constraintStart_toStartOf="@+id/tv_service_name"
        app:layout_constraintTop_toBottomOf="@+id/tv_service_name" />

    <TextView
        android:id="@+id/tv_service_uuid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="UUID"
        android:textColor="@color/black"
        app:layout_constraintBottom_toBottomOf="@+id/tv_uuid_title"
        app:layout_constraintStart_toEndOf="@+id/tv_uuid_title"
        app:layout_constraintTop_toTopOf="@+id/tv_uuid_title" />

    <TextView
        android:id="@+id/tv_service_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:text="PRIMARY SERVICE"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="@+id/tv_service_name"
        app:layout_constraintTop_toBottomOf="@+id/tv_uuid_title" />

</androidx.constraintlayout.widget.ConstraintLayout>

下面我們?cè)赽le包下新建一個(gè)BleUtils類(lèi),代碼如下所示:

object BleUtils {

    private val generic = "-0000-1000-8000-00805F9B34FB"

    /**
     * 獲取藍(lán)牙服務(wù)名稱(chēng)
     * @param uuid UUID
     */
    fun getServiceName(uuid: UUID) =
        when ("0x${uuid.toString().substring(4, 8).uppercase(Locale.getDefault())}") {
            "0x1800" -> "Generic Access service"
            "0x1801" -> "Generic Attribute service"
            "0x1802" -> "Immediate Alert service"
            "0x1803" -> "Link Loss service"
            "0x1804" -> "Tx Power service"
            "0x1805" -> "Current Time service"
            "0x1806" -> "Reference Time Update service"
            "0x1807" -> "Next DST Change service"
            "0x1808" -> "Glucose service"
            "0x1809" -> "Health Thermometer service"
            "0x180A" -> "Device Information service"
            "0x180D" -> "Heart Rate service"
            "0x180E" -> "Phone Alert Status service"
            "0x180F" -> "Battery service"
            "0x1810" -> "Blood Pressure service"
            "0x1811" -> "Alert Notification service"
            "0x1812" -> "Human Interface Device service"
            "0x1813" -> "Scan Parameters service"
            "0x1814" -> "Running Speed and Cadence service"
            "0x1815" -> "Automation IO service"
            "0x1816" -> "Cycling Speed and Cadence service"
            "0x1818" -> "Cycling Power service"
            "0x1819" -> "Location and Navigation service"
            "0x181A" -> "Environmental Sensing service"
            "0x181B" -> "Body Composition service"
            "0x181C" -> "User Data service"
            "0x181D" -> "Weight Scale service"
            "0x181E" -> "Bond Management service"
            "0x181F" -> "Continuous Glucose Monitoring service"
            "0x1820" -> "Internet Protocol Support service"
            "0x1821" -> "Indoor Positioning service"
            "0x1822" -> "Pulse Oximeter service"
            "0x1823" -> "HTTP Proxy service"
            "0x1824" -> "Transport Discovery service"
            "0x1825" -> "Object Transfer service"
            "0x1826" -> "Fitness Machine service"
            "0x1827" -> "Mesh Provisioning service"
            "0x1828" -> "Mesh Proxy service"
            "0x1829" -> "Reconnection Configuration service"
            "0x183A" -> "Insulin Delivery service"
            "0x183B" -> "Binary Sensor service"
            "0x183C" -> "Emergency Configuration service"
            "0x183D" -> "Authorization Control service"
            "0x183E" -> "Physical Activity Monitor service"
            "0x183F" -> "Elapsed Time service"
            "0x1840" -> "Generic Health Sensor service"
            "0x1843" -> "Audio Input Control service"
            "0x1844" -> "Volume Control service"
            "0x1845" -> "Volume Offset Control service"
            "0x1846" -> "Coordinated Set Identification service"
            "0x1847" -> "Device Time service"
            "0x1848" -> "Media Control service"
            "0x1849" -> "Generic Media Control service"
            "0x184A" -> "Constant Tone Extension service"
            "0x184B" -> "Telephone Bearer service"
            "0x184C" -> "Generic Telephone Bearer service"
            "0x184D" -> "Microphone Control service"
            "0x184E" -> "Audio Stream Control service"
            "0x184F" -> "Broadcast Audio Scan service"
            "0x1850" -> " Published Audio Capabilities service"
            "0x1851" -> "Basic Audio Announcement service"
            "0x1852" -> "Broadcast Audio Announcement service"
            "0x1853" -> "Common Audio service"
            "0x1854" -> "Hearing Access service"
            "0x1855" -> "Telephony and Media Audio service"
            "0x1856" -> "Public Broadcast Announcement service"
            "0x1857" -> "Electronic Shelf Label service"
            else -> "Unknown Service"
        }
        
    fun getServiceUUID(uuid: UUID) =
        "0x${uuid.toString().substring(4, 8).uppercase(Locale.getDefault())}"
}

??這里需要說(shuō)明一下藍(lán)牙的UUID,藍(lán)牙UUID(Universally Unique Identifier)是用于唯一標(biāo)識(shí)藍(lán)牙設(shè)備和服務(wù)的一種標(biāo)識(shí)符。它是一個(gè)128位長(zhǎng)的數(shù)字,在藍(lán)牙通信中起到唯一標(biāo)識(shí)的作用。藍(lán)牙UUID按照標(biāo)準(zhǔn)分為兩種類(lèi)型:

  1. 16位UUID:這些UUID通常用于藍(lán)牙標(biāo)準(zhǔn)定義的一些通用服務(wù)和特性。例如,設(shè)備名稱(chēng)服務(wù)的UUID是 00001800-0000-1000-8000-00805F9B34FB。

  2. 128位UUID:這些UUID通常用于自定義的服務(wù)和特性,以確保全球唯一性??梢宰孕猩梢粋€(gè)128位的UUID作為自定義的服務(wù)或特性標(biāo)識(shí)。例如,一個(gè)自定義的服務(wù)UUID可以是 0000XXXX-0000-1000-8000-00805F9B34FB,其中的 XXXX 部分可以是任意的16進(jìn)制數(shù)字。

在藍(lán)牙通信中,設(shè)備使用UUID來(lái)發(fā)布和查找服務(wù)以及識(shí)別特性。UUID是藍(lán)牙設(shè)備之間進(jìn)行通信時(shí)的重要標(biāo)識(shí),確保了設(shè)備和服務(wù)的唯一性。

那么getServiceName()中的鍵你就知道是什么意思了,0x1800就是16進(jìn)制數(shù)字,而對(duì)應(yīng)的值則是SIG定義的,可以參考這個(gè)文檔:Assigned_Numbers.pdf。如果你的值找不到對(duì)應(yīng)的,那說(shuō)明它不是SIG規(guī)范的,你這個(gè)服務(wù)UUID就是自己公司自定義的。

下面我們寫(xiě)適配器,在adapter包下新建一個(gè)ServiceAdapter類(lèi),代碼如下所示:

class ServiceAdapter(
    private val services: List<BluetoothGattService>
) : RecyclerView.Adapter<ServiceAdapter.ViewHolder>() {

    private var mOnItemClickListener: OnItemClickListener? = null

    fun setOnItemClickListener(mOnItemClickListener: OnItemClickListener?) {
        this.mOnItemClickListener = mOnItemClickListener
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val viewHolder = ViewHolder(ItemServiceBinding.inflate(LayoutInflater.from(parent.context), parent, false))
        viewHolder.binding.itemService.setOnClickListener { mOnItemClickListener?.onItemClick(it, viewHolder.adapterPosition) }
        return viewHolder
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.binding.tvServiceName.text = BleUtils.getServiceName(services[position].uuid)
        holder.binding.tvServiceUuid.text = BleUtils.getServiceUUID(services[position].uuid)
    }

    override fun getItemCount() = services.size

    class ViewHolder(itemView: ItemServiceBinding) : RecyclerView.ViewHolder(itemView.root) {
        var binding: ItemServiceBinding

        init {
            binding = itemView
        }
    }
}

這里的代碼就是比較簡(jiǎn)單的,就是基本的寫(xiě)法,下面回到MainActivity中進(jìn)行顯示數(shù)據(jù)。

六、顯示服務(wù)

首先聲明變量:

    private var mServiceAdapter: ServiceAdapter? = null

    private val mServiceList: MutableList<BluetoothGattService> = mutableListOf()

然后實(shí)現(xiàn)OnItemClickListener 接口

class MainActivity : BaseActivity(), BleCallback, OnItemClickListener {

重寫(xiě)onItemClick()函數(shù)。

    override fun onItemClick(view: View?, position: Int) {
        showMsg(mServiceList[position].uuid.toString())
    }

修改onServicesDiscovered()函數(shù),代碼如下所示:

    override fun onServicesDiscovered(services: List<BluetoothGattService>) {
        runOnUiThread {
            mServiceList.clear()
            mServiceList.addAll(services)
            mServiceAdapter ?: run {
                mServiceAdapter = ServiceAdapter(mServiceList)
                binding.rvService.apply {
                    (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
                    layoutManager = LinearLayoutManager(this@MainActivity)
                    adapter = mServiceAdapter
                }
                mServiceAdapter!!.setOnItemClickListener(this@MainActivity)
                mServiceAdapter
            }
            mServiceAdapter!!.notifyDataSetChanged()
        }
    }

這里的寫(xiě)法其實(shí)和掃描設(shè)備哪里如出一轍,下面我們運(yùn)行一下看看,什么效果。
android ble藍(lán)牙調(diào)用 ui線程,藍(lán)牙,BLE連接設(shè)備,BLE發(fā)現(xiàn)服務(wù)

七、源碼

如果對(duì)你有所幫助的話,不妨 StarFork,山高水長(zhǎng),后會(huì)有期~

源碼地址:GoodBle文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-792365.html

到了這里,關(guān)于Android Ble藍(lán)牙App(二)連接與發(fā)現(xiàn)服務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android Ble藍(lán)牙App(三)特性和屬性

    Android Ble藍(lán)牙App(三)特性和屬性

    ??在上一篇中我們完成了連接和發(fā)現(xiàn)服務(wù)兩個(gè)動(dòng)作,那么再發(fā)現(xiàn)服務(wù)之后要做什么呢?發(fā)現(xiàn)服務(wù)只是讓你知道設(shè)備有什么服務(wù),可以做什么事情。 Ble藍(lán)牙App(一)掃描 Ble藍(lán)牙App(二)連接與發(fā)現(xiàn)服務(wù) Ble藍(lán)牙App(三)特性和屬性 Ble藍(lán)牙App(四)UI優(yōu)化和描述符 Ble藍(lán)牙App(五

    2024年02月14日
    瀏覽(22)
  • Android Ble藍(lán)牙App(四)UI優(yōu)化和描述符

    Android Ble藍(lán)牙App(四)UI優(yōu)化和描述符

    ??上一篇中了解了特性和屬性,同時(shí)顯示設(shè)備藍(lán)牙服務(wù)下的特性和屬性,本文中就需要來(lái)使用這些特性和屬性來(lái)完成一些功能。 Ble藍(lán)牙App(一)掃描 Ble藍(lán)牙App(二)連接與發(fā)現(xiàn)服務(wù) Ble藍(lán)牙App(三)特性和屬性 Ble藍(lán)牙App(四)UI優(yōu)化和描述符 Ble藍(lán)牙App(五)數(shù)據(jù)操作 ??

    2024年02月13日
    瀏覽(16)
  • Android Ble藍(lán)牙App(六)請(qǐng)求MTU與顯示設(shè)備信息

    Android Ble藍(lán)牙App(六)請(qǐng)求MTU與顯示設(shè)備信息

    ??在上一篇文章中已經(jīng)了解了數(shù)據(jù)操作的方式,而數(shù)據(jù)交互的字節(jié)長(zhǎng)度取決于我們手機(jī)與藍(lán)牙設(shè)備的最大支持長(zhǎng)度。 Ble藍(lán)牙App(一)掃描 Ble藍(lán)牙App(二)連接與發(fā)現(xiàn)服務(wù) Ble藍(lán)牙App(三)特性和屬性 Ble藍(lán)牙App(四)UI優(yōu)化和描述符 Ble藍(lán)牙App(五)數(shù)據(jù)操作 Ble藍(lán)牙App(六)

    2024年02月04日
    瀏覽(25)
  • Android藍(lán)牙BLE開(kāi)發(fā)

    Android藍(lán)牙BLE開(kāi)發(fā)

    最近正在研究Android的藍(lán)牙BLE開(kāi)發(fā)學(xué)習(xí),以下是自己做的個(gè)人總結(jié) 首先得說(shuō)明什么是低功耗藍(lán)牙BLE,BLE的全稱(chēng)為Bluetooth low energy(或稱(chēng)Blooth LE,BLE),從英文全稱(chēng)便可以知曉其是一種低功耗的藍(lán)牙技術(shù),是藍(lán)牙技術(shù)聯(lián)盟設(shè)計(jì)和銷(xiāo)售的一種個(gè)人局域網(wǎng)技術(shù),旨在用于醫(yī)療保健、運(yùn)

    2023年04月09日
    瀏覽(38)
  • Android -BLE 藍(lán)牙模塊開(kāi)發(fā)

    Android-Ble藍(lán)牙開(kāi)發(fā)Demo示例–掃描,連接,發(fā)送和接收數(shù)據(jù),分包解包(附源碼) - 簡(jiǎn)書(shū) 前言 萬(wàn)物互聯(lián)的物聯(lián)網(wǎng)時(shí)代的已經(jīng)來(lái)臨,ble藍(lán)牙開(kāi)發(fā)在其中扮演著舉重若輕的角色。最近剛好閑一點(diǎn),抽時(shí)間梳理下這塊的知識(shí)點(diǎn)。 涉及ble藍(lán)牙通訊的客戶(hù)端(開(kāi)啟、掃描、連接、發(fā)送... https://

    2024年02月09日
    瀏覽(26)
  • Android低功耗藍(lán)牙(BLE)開(kāi)發(fā)(二)

    在上一篇文章Android低功耗藍(lán)牙(BLE)開(kāi)發(fā)(一)中我們了解了BLE的相關(guān)概念,這里我們來(lái)實(shí)際用代碼演示安卓進(jìn)行BLE連接和通訊的功能。本文代碼基于Android5.0以上(API 21) 1.聲明權(quán)限 在AndroidManifest.xml文件中添加BLE相關(guān)的權(quán)限聲明。 2.判斷設(shè)備是否支持BLE以及藍(lán)牙是否打開(kāi) 3.進(jìn)

    2024年02月09日
    瀏覽(26)
  • 藍(lán)牙 - 關(guān)于BLE的安全連接

    藍(lán)牙 - 關(guān)于BLE的安全連接

    A Basic Introduction to BLE 4.x Security 引言 Bluetooth Low Energy (BLE)正在迅速成為當(dāng)今最常用的無(wú)線標(biāo)準(zhǔn)之一。同樣地,它也越來(lái)越多地被用于傳輸敏感信息的應(yīng)用中。因此,希望將BLE集成到其產(chǎn)品中的設(shè)計(jì)者應(yīng)該了解這項(xiàng)技術(shù)的安全特性和限制。本文試圖對(duì)這些功能做一個(gè)基本的概

    2024年02月01日
    瀏覽(20)
  • windows+python+bleak+BLE低功耗藍(lán)牙通訊連接

    windows+python+bleak+BLE低功耗藍(lán)牙通訊連接

    1.為什么選bleak ??參考這篇知乎:https://zhuanlan.zhihu.com/p/577687336 ??windows端使用python連接常規(guī)的BLE設(shè)備(藍(lán)牙4.0),僅考慮bleak模塊(排除pybluez、pybluez2、pygatt)。 2.本文主要參考 ??本文主要參考bleak的官方文檔:https://github.com/hbldh/bleak 3.本文所用設(shè)備 ??應(yīng)事先學(xué)習(xí)藍(lán)

    2024年02月02日
    瀏覽(22)
  • BLE基礎(chǔ)理論/Android BLE開(kāi)發(fā)示例

    BLE基礎(chǔ)理論/Android BLE開(kāi)發(fā)示例

    參考:https://blog.csdn.net/qq_36075612/article/details/127739150?spm=1001.2014.3001.5502 參考: https://blog.csdn.net/qq_36075612/article/details/122772966?spm=1001.2014.3001.5502 傳統(tǒng)藍(lán)牙是在之前的 1.0.1.2 , 2.0+EDR,2.1+EDR,3.0+EDR 等基礎(chǔ)上發(fā)展和完善起來(lái) 的。 傳統(tǒng)藍(lán)牙可以用與數(shù)據(jù)量比較大的傳輸,如語(yǔ)音,音樂(lè)

    2024年02月15日
    瀏覽(46)
  • ESP32藍(lán)牙實(shí)例-BLE服務(wù)器與客戶(hù)端通信

    在本文中,我們將介紹如何使用低功耗藍(lán)牙在兩個(gè) ESP32 開(kāi)發(fā)板之間執(zhí)行 BLE 服務(wù)器客戶(hù)端通信。 換句話說(shuō),將介紹如何通過(guò) BLE 在兩個(gè) ESP32 開(kāi)發(fā)板之間交換數(shù)據(jù)。 服務(wù)器和客戶(hù)端之間的通信將通過(guò) BLE 進(jìn)行,其中一個(gè) ESP32 板充當(dāng) BLE 服務(wù)器并將傳感器讀數(shù)發(fā)送到 ESP32 客戶(hù)端

    2024年02月09日
    瀏覽(29)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包