首页 > 其他分享 >Android Studio开发学习(八、蓝牙设备连接)

Android Studio开发学习(八、蓝牙设备连接)

时间:2024-08-11 17:58:36浏览次数:13  
标签:void 蓝牙 Studio import new Android public android

引言

        上篇我们介绍了整体蓝牙模块的基本写法Android Studio开发学习(七、蓝牙模块java)-CSDN博客,当然我们检测到蓝牙设备肯定会连接蓝牙,那么如何实现蓝牙连接呢,这篇博客将实现这个功能。

 设备连接

        connectDevice 方法用于在后台线程中尝试连接到指定的蓝牙设备,并在连接成功或失败时显示相应的提示信息。成功时显示“连接成功”的提示并跳转到新 Activity,失败时显示“连接失败”的提示,使用唯一的UUID标识蓝牙服务,并确保UI更新在主线程中完成。

连接成功:

连接失败:

弹窗提示

        我们在上篇博客基础上增加部分代码,使用 AlertDialog 来显示连接状态。先来介绍一下AlertDialog :

        AlertDialog 是 Android 中用于显示警告信息、提示用户操作或要求用户确认操作的对话框组件。它可以显示标题、消息、按钮,甚至是自定义视图。AlertDialog 是通过 AlertDialog.Builder 类来构建和显示的。下面是一个显示简单的消息对话框例子:

new AlertDialog.Builder(context)
    .setTitle("标题")
    .setMessage("消息对话框")
    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            // 用户点击确定按钮后的操作
        }
    })
    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            // 用户点击取消按钮后的操作
        }
    })
    .show();

 蓝牙模块中的 AlertDialog 应用:

实机演示

完整代码

BlueToothActivity.java

package com.example.login.BlueTooth;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
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.io.IOException;
import java.util.ArrayList;
import java.util.UUID;

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 = 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);
                BluetoothDevice device1 = btController.find_device(rightStr);
                connectDevice(device1);
            }
        });

        Button open_Bt = findViewById(R.id.openBT);
        open_Bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                turnOnBt();
            }
        });

        Button close_Bt = findViewById(R.id.closeBT);
        close_Bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getPermision();
                // 关闭蓝牙
                btController.turnOffBlueTooth();
            }
        });

        Button state_Bt = 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 = 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 (BluetoothDevice device1 : bluetoothDevices) {
                    if (device1.getBondState() == BluetoothDevice.BOND_BONDED) {
                        device.add("设备名:" + device1.getName() + "\n" + "设备地址:" + device1.getAddress());
                    } else {
                        device.add("设备名:" + device1.getName() + "\n" + "设备地址:" + device1.getAddress() + "\n" + "连接状态:未知");
                    }
                    adapter1.notifyDataSetChanged();
                }
            }
        });
    }

    @SuppressLint("MissingPermission")
    private void connectDevice(final BluetoothDevice device) {
        final UUID MY_UUID = UUID.randomUUID();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID);
                    socket.connect();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            showAlert("连接成功", "设备名:" + device.getName() + "\n设备地址:" + device.getAddress());
                            // 跳转到新Activity
                            Intent intent = new Intent(BlueToothActivity.this, DataActivity.class);
                            Bundle bundle = new Bundle();
                            bundle.putString("deviceAddr", device.getAddress());
                            intent.putExtras(bundle);
                            startActivity(intent);
                            finish();
                        }
                    });
                } catch (IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            showAlert("连接失败", "设备名:" + device.getName() + "\n设备地址:" + device.getAddress());
                        }
                    });
                }
            }
        }).start();
    }

    private void showAlert(String title, String message) {
        new AlertDialog.Builder(this)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("确定", null)
                .show();
    }

    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为null导致return出错
            assert (BtAdapter != null);
            // 蓝牙状态
            return BtAdapter.isEnabled();
        }

        @SuppressLint("MissingPermission")
        // 获取设备信息
        public ArrayList<BluetoothDevice> getBondedDeviceList() {
            return new ArrayList<>(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>

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

相关文章

  • Android 13.0 禁用adb install 安装app功能
    1.前言 在13.0的系统rom产品开发中,在进行一些定制开发中,对于一些app需要通过属性来控制禁止安装,比如adbinstall也不允许安装,所以就需要熟悉adbinstall的安装流程,然后来禁用adbinstall安装功能,接下来分析下adb下的安装流程,来实现相关的功能2.禁用adbinstall安装app功......
  • visual studio 2022版本中,scanf报错改为scanf_s才能运行的解决方法,添加万能头文件代码
    本文意在解决scanf报错改为scanf_s才能运行的问题,将深入探讨解决方案和操作手法。目录本文意在解决scanf报错改为scanf_s才能运行的问题,将深入探讨解决方案和操作手法。方法一:直接在程序头部添加方法二:路线和保存方式实操例子运用方法二时保存出现没有权限无法保存的解......
  • Android14音频进阶调试之命令播放mp3/aac非裸流音频(八十)
    简介:CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!新书发布:《Android系统多媒体进阶实战》......
  • Android Media Framework(十六)ACodec - Ⅳ
    上一篇文章讲了ACodec的buffer分配过程,有同学读完后提出了一些问题,所以本篇内容是对上一篇文章的补充。本篇内容将会了解GraphicOutputBufferCount的计算方式,复习useBuffer的调用,学习ACodecBufferChannel。1、configureOutputBuffersFromNativeWindow有同学提问使用N......
  • Android Media Framework(十七)ACodec - Ⅴ
    本篇文章我们一起来分析Executing状态下的数据处理流程。首先对上一篇文章做勘误:实际在调用allocateOutputBuffersFromNativeWindow分配buffer时我们会看到,一开始确实是分配了nBufferCountActual个buffer,但是后面又调用cancelBufferToNativeWindow销毁掉了备用的。可能......
  • visual studio code安装与C/C++语言运行
    VisualStudioCode(VSCode)安装与C/C++语言运行需要几个步骤,包括安装VSCode、配置C/C++环境以及安装必要的插件。以下是一个详细的步骤指南:1.安装VSCode访问官网:首先,前往VSCode的官方网站 VisualStudioCode-CodeEditing.Redefined 进行下载。下载并安装:选择......
  • FL Studio水果编曲软件 24.1.1.4239中文版
    水果编曲软件FLStudio 24.1.1.4239中文版是一款官方推出的新版本的音乐编曲方面的软件工具,特别适合喜欢音乐的童鞋,大家可以制作属于自己的音乐作品,童鞋们还不快快来U大师下载使用啦!!FLStudio简称FL,全称FruityLoopsStudio,因此国人习惯叫它"水果"。目前新版本是FLStud......
  • 腾讯地图SDK Android版开发 3 地图图层
    腾讯地图SDKAndroid版开发3地图图层前言腾讯地图图层地图底图类型地图类图层类型常量接口路况图层接口示例代码地图风格类地图底图类型实时路况页面布局控件响应事件地图底图类型实时路况运行效果图前言本文主要介绍腾讯地图图层相关的功能和接口,以及使用方......
  • AutoGen Studio 本地源码构建
    目录一、环境配置1.1创建本地环境1.2下载autogen源码1.3安装依赖2.构建3.运行本文主要介绍AutoGenStudio本地源码构建过程。一、环境配置1.1创建本地环境通过conda创建一个环境,Python3.10+,Node.js14.15.0+。condacreate-nautogenpython=3.111.......
  • Java计算机毕业设计基于Android的校园网上拍卖平台(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在数字化校园建设的浪潮中,学生们对于便捷、高效的二手商品交易需求日益增长。传统的校园跳蚤市场受限于时间、空间等因素,难以满足学生群体对于多样化......