首页 > 编程语言 >Android Studio开发学习(七、蓝牙模块java)

Android Studio开发学习(七、蓝牙模块java)

时间:2024-08-04 08:57:15浏览次数:27  
标签:java 蓝牙 public Studio new import Android android View

引言

        上篇我们已经介绍了蓝牙模块相关布局,所以,今天我们来学习一下功能实现,如何打开关闭蓝牙。(这里DataActivity为蓝牙列表点击设备名连接后跳转界面函数,这里暂时没有设置,只是默认空白界面)

先来介绍一下蓝牙相关概念

        蓝牙是一种无线技术标准,用于短距离内的数据交换。在 Android 设备上,蓝牙技术允许进行设备发现、配对、连接以及数据传输。它广泛应用于音频设备连接、数据同步、远程控制等多个领域。

        在 Android Studio中 进行蓝牙开发,主要是通过调用 Android 平台提供的蓝牙 API,实现设备间的搜索、配对、连接以及数据传输功能。这包括在 AndroidManifest.xml 中声明必要的蓝牙权限,使用 BluetoothAdapter 和 BluetoothSocket(对于经典蓝牙)或 BluetoothGatt(对于BLE)等类进行编程,同时处理用户授权、兼容性问题、电量消耗和数据安全等挑战。

添加允许、权限

        为了确保应用能够安全地访问设备上的特定功能或数据,而不会对其他应用或用户隐私造成潜在威胁,我们需要在 AndroidManifest.xml 中添加蓝牙相关权限。

点击处理

设置和配置一个 ListView 来显示蓝牙设备信息,并处理 ListView 的点击事件。

        为打开、关闭蓝牙、获取蓝牙状态按钮添加点击效果

        为按钮设置点击监听器,用于更新显示已绑定蓝牙设备列表的UI。在点击事件中,它首先尝试获取必要的权限,然后清空现有设备列表,并查询所有已绑定的蓝牙设备。对于每个设备,根据其绑定状态,将设备名称和地址添加到列表中,并立即通知适配器数据已更改。

打开关闭蓝牙

       BlueToothController()方法:用于初始化蓝牙适配器 (BluetoothAdapter)。它调用 BluetoothAdapter.getDefaultAdapter() 来获取当前设备的蓝牙适配器实例,并将其存储在成员变量 BtAdapter 中,这是后续所有蓝牙操作的基础。

   turnOnBuleTooth() 方法:用于打开蓝牙。它首先检查蓝牙是否已启用,如果没有,则通过 IntentBluetoothAdapter.ACTION_REQUEST_ENABLE)请求用户开启蓝牙。这里,它使用 activity.startActivityForResult(intent,requestCode); 来启动一个活动结果(Activity Result)的Intent,这样当蓝牙状态改变时,可以通过请求的 requestCode 在 activity 的 onActivityResult 方法中接收回调。

   turnOffBlueTooth() 方法:用于关闭蓝牙。它首先检查蓝牙是否已启用,如果是,则调用 BtAdapter.disable() 方法来禁用蓝牙。

蓝牙状态

   getBlueToothStatus() 方法:用于获取当前蓝牙的状态(启用或禁用)。它使用 assert 语句来确保 BtAdapter 不为 null(尽管在构造函数中已经进行了初始化,但这是一个好习惯以增强代码的健壮性)。然后,它返回 BtAdapter.isEnabled() 的结果,该结果指示蓝牙是否已启用。

蓝牙列表

   getBondedDeviceList() 方法:这个方法用于获取与设备配对的所有蓝牙设备列表。它调用 BtAdapter.getBondedDevices() 来获取一个 Set<BluetoothDevice> 集合,然后将其转换为一个 ArrayList<BluetoothDevice> 以便更灵活地操作。这个列表包含了所有已配对的蓝牙设备信息。

   find_device 方法用于在蓝牙适配器 (BtAdapter) 中查找具有指定地址 (addr) 的蓝牙设备。它通过调用 BluetoothAdapter 的 getRemoteDevice(String address) 方法来实现这一点,该方法返回一个代表指定蓝牙地址的 BluetoothDevice 对象(如果找到的话),或者在没有找到匹配设备时返回 null

动态申请权限

实机演示

完整代码

BlueTooth.java

package com.example.login.BlueTooth;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.example.login.R;

import java.util.ArrayList;

@SuppressLint("Registered")
public class BlueToothActivity extends AppCompatActivity {
    // 实例化蓝牙控制器
    public BlueToothController btController = new BlueToothController();
    // 蓝牙权限列表
    public ArrayList<String> requestList = new ArrayList<>();
    // 弹窗
    private Toast mToast;
    public ArrayAdapter adapter1;
    //定义一个列表,存蓝牙设备地址,用于显示。
    public ArrayList<String> device = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth);
        // 获取ListView组件
        ListView listView = (ListView) findViewById(R.id.listView1);
        // 实例化ArrayAdapter对象
        adapter1 = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, device);
        // 添加到ListView组件中
        listView.setAdapter(adapter1);
        //ListView的列表点击事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @SuppressLint("MissingPermission")
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                CharSequence content = ((TextView) view).getText();
                //获取蓝牙的名称的地址
                String con = content.toString();
                //已换行为切割
                String[] conArray = con.split("\n");
                //获取蓝牙地址
                String rightStr = conArray[1].substring(5,conArray[1].length());
                BluetoothDevice device1 = btController.find_device(rightStr);
                if (device1.getBondState() == 12){
                    String S = "设备名:" + device1.getName() + "\n" + "设备地址:" + device1.getAddress();
                    if (device.contains(S)){
                        Intent intent = new Intent(BlueToothActivity.this, DataActivity.class);
                        Bundle bundle = new Bundle();
                        bundle.putString("deviceAddr",device1.getAddress());
                        intent.putExtras(bundle);
                        startActivity(intent);
                        finish();
                    }
                }
            }
        });
        Button open_Bt = (Button) findViewById(R.id.openBT);
        open_Bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                turnOnBt();
            }
        });

        Button close_Bt = (Button) findViewById(R.id.closeBT);
        close_Bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getPermision();
                // 关闭蓝牙
                btController.turnOffBlueTooth();
            }
        });
        Button state_Bt = (Button) findViewById(R.id.stateBT);
        state_Bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getPermision();
                // 判断当前蓝牙状态
                boolean ret = btController.getBlueToothStatus();
                // 弹窗显示结果
                showToast("当前蓝牙状态:" + ret);
            }
        });
        Button update_list = (Button) findViewById(R.id.updateList);
        update_list.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("MissingPermission")
            @Override
            public void onClick(View view) {
                getPermision();
                //初始化列表
                device.clear();
                adapter1.notifyDataSetChanged();
                //获取已绑定蓝牙列表
                ArrayList<BluetoothDevice> bluetoothDevices = btController.getBondedDeviceList();
                //更新列表、
                for (int i=0;i<bluetoothDevices.size();i++){
                    BluetoothDevice device1 = bluetoothDevices.get(i);
                    if (device1.getBondState() == 12){
                        device.add("设备名:" + device1.getName() + "\n" + "设备地址:" + device1.getAddress());
                    }else {
                        device.add("设备名:" + device1.getName() + "\n" + "设备地址:" + device1.getAddress() + "\n" + "连接状态:未知" + "\n");
                    }
                    adapter1.notifyDataSetChanged();
                }
            }
        });
    }

    public static class BlueToothController{
        private BluetoothAdapter BtAdapter;
       
        public BlueToothController() {
            // 获取本地的蓝牙适配器
            BtAdapter = BluetoothAdapter.getDefaultAdapter();
        }
        @SuppressLint("MissingPermission")
        //打开蓝牙
        public void turnOnBlueTooth(Activity activity, int requestCode){
            if (!BtAdapter.isEnabled()){
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                activity.startActivityForResult(intent,requestCode);
            }
        }
        @SuppressLint("MissingPermission")
        //关闭蓝牙
        public void turnOffBlueTooth(){
            if (BtAdapter.isEnabled()) {
               BtAdapter.disable();
           }
        }

        //获取蓝牙状态
        public boolean getBlueToothStatus() {
            // 断言,避免BtAdapter为bull导致return出错
            assert (BtAdapter != null);
            // 蓝牙状态
            return BtAdapter.isEnabled();
        }
        @SuppressLint("MissingPermission")
        //获取设备信息
        public ArrayList<BluetoothDevice> getBondedDeviceList() {
            return new ArrayList<BluetoothDevice>(BtAdapter.getBondedDevices());
        }

         //根据蓝牙地址找到相应的设备
        public BluetoothDevice find_device(String addr) {
            return BtAdapter.getRemoteDevice(addr);
        }
    }
    public void turnOnBt(){
        getPermision();
        //打开蓝牙
        btController.turnOnBlueTooth(this,1);
    }

    public void getPermision(){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
            requestList.add(Manifest.permission.BLUETOOTH_SCAN);
            requestList.add(Manifest.permission.BLUETOOTH_ADVERTISE);
            requestList.add(Manifest.permission.BLUETOOTH_CONNECT);
            requestList.add(Manifest.permission.ACCESS_FINE_LOCATION);
            requestList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
            requestList.add(Manifest.permission.BLUETOOTH);
        }
        if(requestList.size() != 0){
            ActivityCompat.requestPermissions(this, requestList.toArray(new String[0]), 1);
        }
    }
    
    public void showToast(String text){
        // 若Toast控件未初始化
        if( mToast == null){
            // 则初始化
            mToast = Toast.makeText(this, text, Toast.LENGTH_SHORT);
        }
        // 否则
        else{
            // 修改显示文本
            mToast.setText(text);
        }
        // 显示
        mToast.show();
    }}

activity_bluetooth.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"
    android:background="@drawable/background1"
    tools:context=".BlueTooth.BlueToothActivity">


    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="136dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toTopOf="@+id/listView1"
        app:layout_constraintGuide_end="206dp"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/openBT"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="打开蓝牙"
        app:layout_constraintBottom_toTopOf="@+id/stateBT"
        app:layout_constraintEnd_toStartOf="@id/guideline1"
        app:layout_constraintHorizontal_bias="0.567"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/closeBT"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="关闭蓝牙"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.473"
        app:layout_constraintStart_toEndOf="@id/guideline1"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/stateBT"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="蓝牙状态"
        app:layout_constraintEnd_toStartOf="@id/guideline1"
        app:layout_constraintHorizontal_bias="0.567"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/openBT" />

    <Button
        android:id="@+id/updateList"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="更新列表"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.473"
        app:layout_constraintStart_toEndOf="@id/guideline1"
        app:layout_constraintTop_toBottomOf="@id/closeBT" />
    
    <TextView
        android:id="@+id/textView1"
        android:layout_width="307dp"
        android:layout_height="46dp"
        android:layout_marginTop="92dp"
        android:background="#2196F3"
        android:gravity="center"
        android:text="蓝牙列表"
        android:textSize="24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.495"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/stateBT" />
    <ListView
        android:id="@+id/listView1"
        android:layout_width="332dp"
        android:layout_height="350dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.491"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView1"
        app:layout_constraintVertical_bias="0.316" />

</androidx.constraintlayout.widget.ConstraintLayout>

标签:java,蓝牙,public,Studio,new,import,Android,android,View
From: https://blog.csdn.net/m0_74325713/article/details/140865968

相关文章

  • 【前端】JavaScript入门及实战131-135
    文章目录131定时器(1)132定时器(2)133定时器(3)134轮播图135tools.js131定时器(1)<!DOCTYPEhtml><html><head><title></title><metacharset="utf-8"><styletype="text/css"> *{ margin:0; padding:0......
  • 【前端】JavaScript入门及实战136-140
    文章目录136类的操作137二级菜单138JSON139JSON140json2.js136类的操作<!DOCTYPEhtml><html><head><title></title><metacharset="utf-8"><styletype="text/css"> .b1{ width:100px; height:100p......
  • JAVA游戏源码:魔塔&大学生练手项目&java学习项目
    学习java朋友们,福利来了,今天小编给大家带来了一款魔塔源码。注意:此源码仅供学习使用!!视频演示  源码搭建和讲解启动main入口://************************************************************************//************完整源码移步:gitee典康姆/had......
  • Android最全8万字Fragment面试题及参考答案(持续更新)
    目录什么是Fragment?Fragment和Activity之间的关系是什么?为什么要使用Fragment而不是直接使用多个Activity?Fragment是如何被添加到Activity中的?如何从Activity中移除一个Fragment?Fragment可以嵌套吗?如何实现?如何获取当前Activity中的Fragment?如何通过FragmentManager......
  • JavaFX 如何使用内置的对话框
    消息对话框(Alert)JavaFX的Alert类别其实就是我们熟知的MessageDialog,根据消息类型的不同,分为几种不同的AlertType,在显示时也会有不同的图标以及不同的按钮。分类可列表如下:None:不分类的消息。常用于显示使用说明。Information:一般的提示消息。常用于提示目前程序运行的状态,以......
  • github克隆项目到Visual Studio 2022出错怎么回事?
    到底咋回事啊?不同的方法有不同的出错方式。。。。先是选择"用vs打开",结果:然后选择自己输入,结果:救救我,找了各种方法,git也配置了邮箱,密钥也加到github设置里了,github网页用了watttllokit也能打开,怎么就是没法克隆呢,救救救,到底是哪里的错误?????......
  • JAVA游戏源码:仙剑奇侠传|大学生练手项目
    视频演示   源码搭建和讲解启动main入口://************************************************************************//************完整源码移步:gitee典康姆/hadluo/java_game01.git*********//***********************************************......
  • 基于Java的蛋糕甜品管理系统设计与实现(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示项目运行截图技术框架后端采用SpringBoot框架前端框架Vue可行性分析系统测试系统测试的目的系统功能测试数据库表设计代码参考数据库脚本为什么选择我?获取源码前言......
  • Java学习第五周
    packagecom.sxt;publicclassTestSwitch01{publicstaticvoidmain(String[]args){intgrade=(int)(Math.random()*4)+1;//大学的年级switch(grade){case1:System.out.println("大一");break;case2:System.out.println("大二");break;case3:......
  • 日撸Java三百行(day12:顺序表二)
    目录一、关于昨天的补充1.final关键字2.toString()方法二、今日代码实现1.顺序表的查找操作2.顺序表的插入操作3.顺序表的删除操作4.数据测试总结一、关于昨天的补充1.final关键字publicstaticfinalintMAX_LENGTH=10;在昨天的这行代码中,用到了final关键字......