Android 之 藍牙通信(2.0 經典)

???一、環境配置??

1. ??添加依賴??

在?build.gradle?中添加庫依賴:

dependencies {implementation 'com.github.akexorcist:bluetoothspp:1.0.0'  
}
2. ??權限聲明(AndroidManifest.xml)?
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Android 12+ 額外權限 -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 6.0+ 需要 --> [4,8](@ref)

二、頁面布局(activity_main.xml)

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><!-- 狀態顯示 --><TextViewandroid:id="@+id/tv_status"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="藍牙未連接"android:textSize="18sp"/><!-- 設備列表 --><ListViewandroid:id="@+id/lv_devices"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/><!-- 操作按鈕 --><Buttonandroid:id="@+id/btn_scan"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="掃描設備"/><Buttonandroid:id="@+id/btn_send"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="發送數據"android:enabled="false"/> <!-- 默認禁用 --></LinearLayout>

???三、核心代碼(MainActivity.java)?

1. ??初始化藍牙服務?

public class MainActivity extends AppCompatActivity {private BluetoothSPP bt;private TextView tvStatus;private Button btnScan, btnSend;private ListView lvDevices;private List<BluetoothDevice> deviceList = new ArrayList<>();private ArrayAdapter<String> adapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tvStatus = findViewById(R.id.tv_status);btnScan = findViewById(R.id.btn_scan);btnSend = findViewById(R.id.btn_send);lvDevices = findViewById(R.id.lv_devices);// 初始化設備列表適配器adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);lvDevices.setAdapter(adapter);// 初始化藍牙bt = new BluetoothSPP(this);if (!bt.isBluetoothAvailable()) {Toast.makeText(this, "藍牙不可用", Toast.LENGTH_SHORT).show();finish();}// 設置數據接收監聽器bt.setOnDataReceivedListener((data, message) -> {tvStatus.setText("收到數據: " + message); // [1,6](@ref)});// 設置連接狀態監聽器bt.setBluetoothConnectionListener(new BluetoothSPP.BluetoothConnectionListener() {@Overridepublic void onDeviceConnected(String name, String address) {tvStatus.setText("已連接至 " + name);btnSend.setEnabled(true); // 啟用發送按鈕}@Overridepublic void onDeviceDisconnected() {tvStatus.setText("連接斷開");btnSend.setEnabled(false);}@Overridepublic void onDeviceConnectionFailed() {tvStatus.setText("連接失敗");}});// 啟動藍牙服務bt.setupService();bt.startService(BluetoothState.DEVICE_OTHER); // [1,6](@ref)// 掃描按鈕事件btnScan.setOnClickListener(v -> scanDevices());// 發送按鈕事件btnSend.setOnClickListener(v -> sendData());// 設備列表點擊事件lvDevices.setOnItemClickListener((parent, view, position, id) -> {BluetoothDevice device = deviceList.get(position);connectDevice(device.getAddress()); // 連接選中的設備 [3](@ref)});}// 掃描設備private void scanDevices() {if (!checkPermissions()) {requestPermissions(); // 動態申請權限return;}deviceList.clear();adapter.clear();bt.setDeviceTarget(BluetoothState.DEVICE_OTHER);bt.startDiscovery(); // 開始掃描 [6](@ref)// 注冊廣播接收器IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(discoveryReceiver, filter);}// 廣播接收器(處理設備發現)private final BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (BluetoothDevice.ACTION_FOUND.equals(action)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);deviceList.add(device);adapter.add(device.getName() + "\n" + device.getAddress()); // 顯示設備名和地址 [8](@ref)}}};// 連接設備(帶延遲避免沖突)private void connectDevice(String address) {new Handler().postDelayed(() -> {bt.connect(address); // 延遲500ms連接 [3](@ref)}, 500);}// 發送數據private void sendData() {bt.send("Hello Device!", true); // 發送字符串(自動添加CR/LF)[1](@ref)}// 權限檢查(兼容Android 12+)private boolean checkPermissions() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {return checkSelfPermission(BLUETOOTH_SCAN) == PERMISSION_GRANTED && checkSelfPermission(BLUETOOTH_CONNECT) == PERMISSION_GRANTED;} else {return checkSelfPermission(ACCESS_FINE_LOCATION) == PERMISSION_GRANTED;}}// 動態請求權限private void requestPermissions() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {requestPermissions(new String[]{Manifest.permission.BLUETOOTH_SCAN,Manifest.permission.BLUETOOTH_CONNECT,Manifest.permission.ACCESS_FINE_LOCATION}, 1);} else {requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);}}@Overrideprotected void onDestroy() {super.onDestroy();unregisterReceiver(discoveryReceiver); // 注銷廣播bt.stopService(); // 釋放資源 [6](@ref)}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91881.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91881.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91881.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 Scikit-LLM 進行零樣本和少樣本分類

使用 Scikit-LLM 進行零樣本和少樣本分類 使用 Scikit-LLM 進行零樣本和少樣本分類 在本文中&#xff0c;您將學習&#xff1a; Scikit-LLM如何將OpenAI的GPT等大型語言模型與Scikit-learn框架集成以進行文本分析。零樣本和少樣本分類之間的區別以及如何使用Scikit-LLM實現它…

android內存作假通殺補丁(4GB作假8GB)

可過如下app檢測&#xff1a; 安兔兔、魯大師、白眼、AIDA64、CPU X、CPU-Z、DevCheck、DeviceInfoHW lyw235yk235:~/Extend/lyw235/V/sprdroid1_v_4/sprdroid1_v$ git diff vnd/bsp/kernel5.15/kernel5.15/mm/page_alloc.c diff --git a/vnd/bsp/kernel5.15/kernel5.15/mm/pag…

Android 之 MVC架構

介紹1. MVC架構分工????Model層??&#xff1a;處理數據驗證、網絡請求等業務邏輯。??View層??&#xff1a;XML布局定義界面&#xff0c;Activity處理用戶輸入和顯示結果。??Controller層??&#xff1a;Activity作為控制器&#xff0c;協調Model和View的交互對于登…

Centos Docker 安裝手冊(可用)

Centos 安裝 Docker # 卸載舊版 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine \docker-selinux # 安裝依賴工具 yum install -y yum-utils device-mapper-persistent-d…

烽火HG680-KX-海思MV320芯片-2+8G-安卓9.0-強刷卡刷固件包

烽火HG680-KX-海思MV320芯片-28G-安卓9.0-強刷卡刷固件包U盤強刷刷機步驟&#xff1a;1、強刷刷機&#xff0c;用一個usb2.0的8G以下U盤&#xff0c;fat32&#xff0c;2048塊單分區格式化&#xff08;強刷對&#xff35;盤非常非常挑剔&#xff0c;usb2.0的4G U盤兼容的多&…

Python爬蟲實戰:研究pycares技術構建DNS解析系統

1. 引言 1.1 研究背景 隨著互聯網的飛速發展,網絡上的數據量呈現爆炸式增長。網絡爬蟲作為一種高效的數據采集工具,被廣泛應用于數據分析、市場調研、學術研究等領域。傳統的爬蟲在進行大規模數據采集時,往往會受到 DNS 解析效率的制約,成為影響爬取性能的瓶頸之一。 DNS…

從 0 到 1 認識 Spring MVC:核心思想與基本用法(下)

文章目錄&#x1f4d5;4. 響應??4.1 返回靜態頁面??4.2 返回數據ResponseBody???4.3 返回HTML代碼片段???4.4 返回JSON??4.5 設置狀態碼??4.6 設置Header&#xff08;了解&#xff09;&#x1f4d5;5. 案例練習??5.1 加法計算器??5.2 用戶登錄??5.3 留言板…

Python-初學openCV——圖像預處理(五)——梯度處理、邊緣檢測、圖像輪廓

目錄 一、圖像梯度處理 1、垂直邊緣提取 2、Sobel算子 3、Laplacian算子 二、圖像邊緣檢測 1、高斯濾波 2、計算圖像的梯度、方向 3、非極大值抑制 4、雙閾值篩選 三、繪制圖像輪廓 1、概念 2、尋找輪廓 3、繪制輪廓 一、圖像梯度處理 還記得高數中的一階導數求極值…

【Redis】安裝Redis,通用命令,常用數據結構,單線程模型

目錄 一.在Ubuntu系統安裝Redis 二. redis客戶端介紹 三. 全局命令 3.1.GET和SET命令 3.2.KEYS&#xff08;生產環境禁止使用&#xff09; 3.3.EXISTS 3.4.DEL 3.5.EXPIRE 3.6.TTL 3.6.1.Redis的過期策略 3.6.2.基于優先級隊列/堆的實現去實現定時器 3.6.3.定時器&a…

ubuntu22.04系統實踐 linux基礎入門命令(三) 用戶管理命令

以下有免費的4090云主機提供ubuntu22.04系統的其他入門實踐操作 地址&#xff1a;星宇科技 | GPU服務器 高性能云主機 云服務器-登錄 相關兌換碼星宇社區---4090算力卡免費體驗、共享開發社區-CSDN博客 之所以推薦給大家使用&#xff0c;是因為上面的云主機目前是免費使用的…

DPDK中的TCP頭部處理

1. TCP頭部結構 TCP頭部通常為20字節&#xff08;不含可選字段&#xff09;&#xff0c;每個字段占據固定的字節位置。以下是TCP頭部的結構&#xff0c;按字節位置逐一說明&#xff1a;0 1 2 30 1 2 3 4 5 6 7 8 9 0 1 …

開源在線客服系統Chatwoot配置文件

參考&#xff1a; https://developers.chatwoot.com/self-hosted/deployment/dockerhttps://developers.chatwoot.com/self-hosted/deployment/docker 1、.env 配置文件 # Learn about the various environment variables at # https://www.chatwoot.com/docs/self-hosted/co…

PHP進階語法詳解:命名空間、類型轉換與文件操作

掌握了PHP面向對象編程的基礎后&#xff0c;就可以深入學習命名空間、類型轉換、文檔注釋、序列化以及文件操作等重要概念。 1、命名空間&#xff08;Namespace&#xff09; 命名空間是PHP 5.3引入的重要特性&#xff0c;它解決了類名、函數名和常量名沖突的問題&#xff0c;使…

Webpack 搭建 Vue3 腳手架詳細步驟

創建一個新的 Vue 項目 1&#xff09;初始化項目目錄 新建一個文件夾&#xff0c;或者使用以下指令 mkdir webpack-vue_demo cd webpack-vue_demo2&#xff09;初始化 npm 項目 npm init -y3&#xff09;安裝 vue 和 webpack 相關依賴 npm install vue vue-loader vue-template…

【Git 誤操作恢復指南】

Git 誤操作恢復指南 適用場景&#xff1a;git reset --hard 誤操作后的緊急恢復 風險等級&#xff1a;&#x1f534; 高風險 - 可能導致代碼丟失 恢復成功率&#xff1a;95%&#xff08;CI/CD 環境下&#xff09; &#x1f6a8; 緊急情況概述 問題描述 在項目開發過程中&am…

Go語言 逃 逸 分 析

逃逸分析是什么 逃逸分析是編譯器用于決定變量分配到堆上還是棧上的一種行為。一個變量是在堆上分配&#xff0c;還是在棧上分配&#xff0c;是經過編譯器的逃逸分析之后得出的“結論”。Go 語言里編譯器的逃逸分析&#xff1a;它是編譯器執行靜態代碼分析后&#xff0c…

LeetCode算法日記 - Day 1: 移動零、復寫零

目錄 1. 移動零 1.1 思路解析 1.2 代碼實現 2. 復寫零 2.1 思路解析 2.2 代碼實現 1. 移動零 283. 移動零 - 力扣&#xff08;LeetCode&#xff09; 給定一個數組 nums&#xff0c;編寫一個函數將所有 0 移動到數組的末尾&#xff0c;同時保持非零元素的相對順序。 請…

Odoo:免費開源的醫療器械行業解決方案

開源智造Odoo專家團隊深知&#xff0c;作為醫療器械制造商&#xff0c;您的成功取決于制造卓越產品的能力。您必須遵循嚴密控制的流程&#xff0c;開發和制造出達到最嚴格質量標準的產品。“開源智造Odoo醫療器械行業解決方案”是為醫療器械制造商設計的全球企業資源規劃(ERP)軟…

Redis鍵值對中值的數據結構

前言 前面我們已經介紹了Redis的鍵值對存儲管理的底層數據結構。如果不清楚的同志可以看我前面的博客 Redis數據庫存儲鍵值對的底層原理-CSDN博客 下面,我們來看一下Redis鍵值對中值的數據結構有那些叭 Redis常見的5種數據類型 string …

MySQL自動化安裝工具-mysqldeploy

功能 可在linux系統上安裝 mysql5.5/5.6/5.7/8.0/8.4 版本的 MySQL&#xff0c;可以初始化多實例 MySQL。 碼云: https://gitee.com/hh688/mysqldeploy guithub: https://github.com/hhkens/mysqldeploy 限制 僅在 centos7 環境進行測試&#xff0c;后期可能支持更多系統。 此程…