【Android开发基础】蓝牙信息的获取(Bluetooth)

news2024/12/23 20:23:46

文章目录

    • 一、引言
    • 二、操作
      • 1、权限
      • 2、开启蓝牙
      • 3、可检测
      • 4、搜索蓝牙
      • 5、广播
    • 三、附件
      • 1、UI界面设计
      • 2、总代码

一、引言

  • 描述:蓝牙技术是一种无线数据和语音通信开放的全球规范,它是基于低成本的近距离无线连接,为固定和移动设备建立通信环境的一种特殊的近距离无线技术连接。蓝牙使当前的一些便携移动设备和计算机设备能够不需要电缆就能连接到互联网,并且可以无线接入互联网。在生活中也是得到广泛的应用,比如:车载蓝牙、公共洗衣机。
  • 频段:2.4—2.485GHz的ISM波段
  • 特点:(摘选引用自百度百科)
    1、蓝牙技术的适用设备多,无需电缆,通过无线使电脑和电信连网进行通信。
    2、蓝牙技术的工作频段全球通用,适用于全球范围内用户无界限的使用,解决了蜂窝式移动电话的国界障碍。
    3、蓝牙技术的安全性和抗干扰能力强,由于蓝牙技术具有跳频的功能,有效避免了ISM频带遇到干扰源。
    4、现阶段,蓝牙技术的主要工作范围在10米左右,经过增加射频功率后的蓝牙技术可以在100米的范围进行工作,只有这样才能保证蓝牙在传播时的工作质量与效率,提高蓝牙的传播速度。
  • 知识点:
    1、Bluetooth
    2、广播
  • 难度:初级
  • 效果:
    在这里插入图片描述

二、操作

        因为进度问题,防止劝退初学者,所以此篇博客只会描述如何开启蓝牙、打开可检测设置和搜索蓝牙,关于蓝牙连接和蓝牙通信我会将TCP和UDP数据通信放在一起,综合成一篇进阶中级难度的博客。

1、权限

         需要在 AndroidManifest.xml 中添加以下权限,防止开启蓝牙失败,并接收不到提醒。

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

        主界面.java 权限二次判断,在SDK23以上的版本都需要加上这个权限判断,要不然第一次拒绝之后,可能无法再次弹出提醒,需要用户手动开启权限。

	private void requestPermission() {
        if (Build.VERSION.SDK_INT >= 23 && !isPermissionR){
            isPermissionR = true;
            ArrayList<String> permissionsList = new ArrayList<>();
            String[] permissions = {
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,
            };
            for (String perm : permissions) {
                if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(MainActivity.this,perm)) {
                    permissionsList.add(perm);
                }
            }
            if (!permissionsList.isEmpty()) {
                String[] strings = new String[permissionsList.size()];
                ActivityCompat.requestPermissions(MainActivity.this , permissionsList.toArray(strings),0);
            }
        }
    }

2、开启蓝牙

通过Intent机制发送请求,开启蓝牙。

   //获得BluetoothAdapter对象,启动API
   BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
   
   //判断本机是否有蓝牙设备
   if (bluetoothAdapter == null) {
       text.setText("本机无蓝牙设备\n");
   } else if (!bluetoothAdapter.isEnabled()) {
       //若手机蓝牙未开启,将启动蓝牙设备
       Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
       //发送请求,开启蓝牙
       startActivityForResult(intent , 300);
       bluetoothAdapter.cancelDiscovery();
       requestPermission();
   } else {
       Toast.makeText(MainActivity.this , "蓝牙已开启", Toast.LENGTH_SHORT).show();
   }

3、可检测

只有打开可检测才能被其他应用所检测到。

    if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
        showToast("请先开启本机蓝牙");
        return;
    }
    if (bluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
        //不可被检测性
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
        //使本机可在 500秒 内可被检测到
        intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,500);
        startActivity(intent);
    } else {
        showToast("本机已处于被检测状态!!");
    }

4、搜索蓝牙

这里使用Set方法获取到蓝牙信息。

    if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
        showToast("请先开启本机蓝牙");
        return;
    }
    foundInfo = "发现蓝牙设备:\n"; // 将搜索结果字符串恢复成初始值
    bluetoothAdapter.startDiscovery();
    // 收集蓝牙信息
    Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
    if(pairedDevices.size()>0)
    {
        String pairedInfo = "可配对的蓝牙设备:\n";
        for(Iterator<BluetoothDevice> it = pairedDevices.iterator(); it.hasNext();)
        {
            BluetoothDevice pairedDevice = (BluetoothDevice)it.next();
            //显示出远程蓝牙设备的名字和物理地址
            pairedInfo += pairedDevice.getName()+"  "+pairedDevice.getAddress()+"\n";
        }
        text.setText(pairedInfo);
    }

	class BluetoothReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            //获得扫描到的远程蓝牙设备
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            foundInfo += device.getName()+"  "+device.getAddress()+"\n";
        }
        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { //搜索结束
            if (foundInfo.equals("发现蓝牙设备:\n")) {
                Toast.makeText(MainActivity.this , "没有搜索到蓝牙设备" , Toast.LENGTH_SHORT).show();
            }
            else {
                //显示搜索结果
                text.setText(foundInfo);
                text.setMovementMethod(ScrollingMovementMethod.getInstance());
            }
        }

5、广播

广播是蓝牙检测中最重要的一环。

		//创建蓝牙广播信息
        bluetoothReceiver = new BluetoothReceiver();
        //设定广播接收的filter
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        //注册广播接收器,当设备被发现时调用函数
        registerReceiver(bluetoothReceiver , filter);
        //设定另一事件广播
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        //注册广播接收器
        registerReceiver(bluetoothReceiver,filter);

三、附件

1、UI界面设计

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_kq"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="打开蓝牙"
        android:background="@drawable/shape"/>

    <Button
        android:id="@+id/btn_jcx"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="启动附近可检测"
        android:background="@drawable/shape"/>

    <Button
        android:id="@+id/btn_ss"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="搜索附近可配对"
        android:background="@drawable/shape"/>

    <TextView
        android:id="@+id/bluetooth_text"
        android:layout_width="match_parent"
        android:layout_marginTop="40dp"
        android:scrollbars="vertical"
        android:fadeScrollbars="false"
        android:layout_height="wrap_content"/>

</LinearLayout>

2、总代码

public class MainActivity extends AppCompatActivity {

    private Button btnDk,btnKj,btnSs;
    private TextView text;
    private String foundInfo = null;
    //获得BluetoothAdapter对象,启动API
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    BluetoothReceiver bluetoothReceiver;
    private boolean isPermissionR = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
    }

    private void init() {
        text = findViewById(R.id.bluetooth_text);
        //开启蓝牙
        btnDk = findViewById(R.id.btn_kq);
        btnDk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //判断本机是否有蓝牙设备
                if (bluetoothAdapter == null) {
                    text.setText("本机无蓝牙设备\n");
                } else if (!bluetoothAdapter.isEnabled()) {
                    //若手机蓝牙未开启,将启动蓝牙设备
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    //发送请求,开启蓝牙
                    startActivityForResult(intent , 300);
                    bluetoothAdapter.cancelDiscovery();
                    requestPermission();
                } else {
                    showToast("蓝牙已开启");
                }
            }
        });

        btnKj = findViewById(R.id.btn_jcx);
        btnKj.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
                    showToast("请先开启本机蓝牙");
                    return;
                }
                if (bluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
                    //不可被检测性
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
                    //使本机可在 500秒 内可被检测到
                    intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,500);
                    startActivity(intent);
                } else {
                    showToast("本机已处于被检测状态!!");
                }
            }
        });

        btnSs = findViewById(R.id.btn_ss);
        btnSs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
                    showToast("请先开启本机蓝牙");
                    return;
                }
                foundInfo = "发现蓝牙设备:\n"; //将搜索结果字符串恢复成初始值
                bluetoothAdapter.startDiscovery();
                Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
                if(pairedDevices.size()>0)
                {
                    String pairedInfo = "可配对的蓝牙设备:\n";
                    for(Iterator<BluetoothDevice> it = pairedDevices.iterator(); it.hasNext();)
                    {
                        BluetoothDevice pairedDevice = (BluetoothDevice)it.next();
                        //显示出远程蓝牙设备的名字和物理地址
                        pairedInfo += pairedDevice.getName()+"  "+pairedDevice.getAddress()+"\n";
                    }
                    text.setText(pairedInfo);
                }
            }
        });

        //创建蓝牙广播信息
        bluetoothReceiver = new BluetoothReceiver();
        //设定广播接收的filter
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        //注册广播接收器,当设备被发现时调用函数
        registerReceiver(bluetoothReceiver , filter);
        //设定另一事件广播
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        //注册广播接收器
        registerReceiver(bluetoothReceiver,filter);
    }


    class BluetoothReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                //获得扫描到的远程蓝牙设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                foundInfo += device.getName()+"  "+device.getAddress()+"\n";
            }
            else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { //搜索结束
                if (foundInfo.equals("发现蓝牙设备:\n")) {
                    Toast.makeText(MainActivity.this , "没有搜索到蓝牙设备" , Toast.LENGTH_SHORT).show();
                }
                else {
                    //显示搜索结果
                    text.setText(foundInfo);
                    text.setMovementMethod(ScrollingMovementMethod.getInstance());
                }
            }
        }
    }

    public void showToast(String string) {
        Toast.makeText(MainActivity.this , string , Toast.LENGTH_SHORT).show();
    }

    private void requestPermission() {
        if (Build.VERSION.SDK_INT >= 23 && !isPermissionR){
            isPermissionR = true;
            ArrayList<String> permissionsList = new ArrayList<>();
            String[] permissions = {
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION,
            };
            for (String perm : permissions) {
                if (PackageManager.PERMISSION_GRANTED != ActivityCompat.checkSelfPermission(MainActivity.this,perm)) {
                    permissionsList.add(perm);
                }
            }
            if (!permissionsList.isEmpty()) {
                String[] strings = new String[permissionsList.size()];
                ActivityCompat.requestPermissions(MainActivity.this , permissionsList.toArray(strings),0);
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/650803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为OD机试真题 JavaScript 实现【知识图谱新词挖掘1】【2023Q1 100分】

一、题目描述 小华负责公司知识图谱产品&#xff0c;现在要通过新词挖掘完善知识图谱。 新词挖掘: 给出一个待挖掘文本内容字符串Content和一个词的字符串word&#xff0c;找到content中所有word的新词。 新词&#xff1a;使用词word的字符排列形成的字符串。 请帮小华实现新词…

cesium学习(相机)

飞到一个地方 如果你知道位置的经纬度和高度&#xff0c;你可以使用相机的flyTo功能直接飞到CesiumJS中的那个位置。 viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0), });更改相机的方向 flyTo要在完成后更改相机的方向&#x…

一、网络协议和常用的网络工具

文章目录 1.计算机概论1.1 计算机网络是什么&#xff1f;1.2 计算机网络的层次结构 2.TCP/IP详解2.1 TCP/IP协议族2.2 网络传输中的数据2.3 网路通信中的地址和端口号2.4 TCP三次握手建立连接2.5 TCP四次挥手建立连接 3.网络工具Wireshark和tcpdump4.一次完整的Http请求过程 1.…

Live Demo精彩大放送,演绎openGauss技术创新

技术是开源社区的根基&#xff0c;创新是推动技术发展的源动力。openGauss开源三周年&#xff0c;携手开发者、社区伙伴、用户&#xff0c;持续聚焦内核竞争力、用户场景架构创新、完善周边生态工具。5月26日&#xff0c;openGauss Developer Day 2023 主论坛现场&#xff0c;1…

自定义包含天时分的时长选择器组件

场景&#xff1a;项目是reactantd 实现的。如果传感器超过3天4小时没有上报数据&#xff0c;则认为设备已经坏了&#xff0c;需要发出告警。 3天4小时这是由用户在前端页面输入的&#xff0c;因此需要有一个时长选择器。antd 原生的TimePicker 组件只能实现选择 时、分、秒&…

(Qt)day4

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QDebug> #include <QMainWindow> #include <QMessageBox> #include <QTimer> //定时器类头文件 #include <QTime> //时间类的头文件 #include <QTimerEvent> //定时器…

k8s的service资源类型有ClusterIP、Nodeport、ExternalName、LoadBalancer、Headless(None)

1. ClusterIP 是什么 ClusterIP 是在所有节点内生成一个虚拟IP&#xff0c;为一组pod提供统一的接入点&#xff0c;当service存在时&#xff0c;它的IP地址和端口不会发生改变&#xff0c;客户端通过service的ip和端口建立连接&#xff0c;由service将连接路由到该服务的任意一…

基于深度学习的人脸识别与检测方案

一、项目介绍前言 人脸识别作为一种生物特征识别技术&#xff0c;具有非侵扰性、非接触性、友好性和便捷性等优点。人脸识别通用的流程主要包括人脸检测、人脸裁剪、人脸校正、特征提取和人脸识别。人脸检测是从获取的图像中去除干扰&#xff0c;提取人脸信息&#xff0c;获取人…

使用ASM在Android中进行字节码注入

目录 使用方法 1.编译使用插件 这里自定义了一个插件用来对字节码进行操作 首先我们需要找到这个Gradle任务&#xff0c;双击进行编译打包 打包成功后会生成如下目录 然后我们需要在项目的gradle文件中进行引用 然后在application的model下的gradle中应用插件 2.使用ASM清…

【裸机开发】中断系统(二)—— Reset 中断服务函数(汇编实现)

目录 一、Reset 中断服务函数的实现步骤 二、汇编实现 Reset 中断服务函数 1、禁止/打开全局中断 2、设置SP指针 3、清除 .bss 段 4、完整 Reset 中断服务函数 一、Reset 中断服务函数的实现步骤 实现 Reset 中断服务函数的基本步骤如下&#xff1a; 设置各个模式下的S…

发布Android Lib 到 MavenCentral

新建 Sonatype 项目 注册账号&#xff1a; https://issues.sonatype.org/secure/Signup!default.jspa 这里注册不需要什么验证码&#xff0c;很简单。 创建问题 点击新建&#xff1a; 概要&#xff1a;自定义&#xff0c;写项目名称即可。 GroupId&#xff1a;如果是git…

C语音:打印整数二进制的奇数位和偶数位

题目&#xff1a; 获取一个整数二进制序列中所有的偶数位和奇数位&#xff0c;分别打印出二进制序列 思路&#xff1a; 总体思路&#xff1a; &#xff08;一&#xff09;. 输入数据 &#xff08;二&#xff09;. 打印奇数位&#xff1a; 使用 for循环 循环产生 1~32 之间的偶…

2023年5月 青少年软件编程(图形化) 等级考试试卷(一级)

青少年软件编程&#xff08;图形化&#xff09; 等级考试试卷&#xff08;一级&#xff09;2023.6 一、 单选题(共 25 题&#xff0c; 共 50 分) 1.看图找规律&#xff0c; 请问下图红框中是&#xff1f; &#xff08; &#xff09; A. B. C. D. 标准答案&#xff1a; D 试题解…

centos系统把.net6 web api部署到docker

为了搞定docker是怎么部署的&#xff0c;做个笔记 前提条件准备一个core项目,使用vs自带的docker打包假如你选择docker支持的时候不小心安装了Docker Desktop&#xff1b;还可以简单的先部署到本地docker中发布到centosdocker常用命令 前提条件 一台centos 8.0 版本以上的linu…

软件测试的7年,我秃了,也变强了...

当前就业环境&#xff0c;裁员、失业消息满天飞&#xff0c;好像能有一份工作就不错了&#xff0c;更别说高薪。其实这只是一方面。另一方面&#xff0c;各大企业依然求贤若渴&#xff0c;高技术人才依然紧缺&#xff0c;只要技术过硬&#xff0c;拿个年包50w不是问题。 人生格…

i.MX RT1010跨界MCU(MCUXpresso IDE上手体验)

MCUXpresso IDE是专为NXP半导体的基于ARM Cortex-M内核的MCU芯片开发而设计的&#xff0c;其优势主要体现在以下几个方面&#xff1a; MCUXpresso IDE集成了MCUXpresso SDK&#xff0c;这是NXP提供的一个软件开发套件&#xff0c;包含了底层驱动、中间件以及大量的示例代码和应…

Charles Windows10使用 证书安装 过期重设 证书加入到受信任根目录 配置访问WhatsApp

普通教程文档 抓包神器 Charles 使用教程详解 - 知乎 界面选项详细讲解 Charles的功能介绍与使用教程&#xff0c;一学就会&#xff0c;不信就来试试&#xff1f; 疑难杂症 由于CA 根证书不在“受信任的根证书颁发机构”存储区中&#xff0c;所以它不受信任 1、winr 运行…

SandQuant停止运营,免费获取A股数据

亲爱的各位朋友们&#xff1a; SandQuant即日起不再对外提供任何服务&#xff0c;为了感恩曾经支持过我们的客户朋友&#xff0c;现免费提供所有A股数据&#xff08;数据非常庞大&#xff0c;请酌情下载&#xff09;&#xff0c;请通过链接自取。 请关注我们获取链接&#xff…

产品不可或缺的文档——帮助文档

在互联网时代&#xff0c;产品的更新迭代速度越来越快&#xff0c;产品功能也越来越复杂&#xff0c;为了让用户能够更好地理解和使用产品&#xff0c;帮助文档逐渐成为了产品不可或缺的一部分。本文将从帮助文档的作用、设计原则、撰写技巧等方面探讨帮助文档的重要性及如何编…

【AI面试】损失函数(Loss),定义、考虑因素,和怎么来的

神经网络学习的方式,就是不断的试错。知道了错误,然后沿着错误的反方向(梯度方向)不断的优化,就能够不断的缩小与真实世界的差异。 此时,如何评价正确答案与错误答案,错误的有多么的离谱,就需要一个评价指标。这时候,损失和损失函数就运用而生。 开始之前,我们先做…