引言
上篇我们已经介绍了蓝牙模块相关布局,所以,今天我们来学习一下功能实现,如何打开关闭蓝牙。(这里DataActivity为蓝牙列表点击设备名连接后跳转界面函数,这里暂时没有设置,只是默认空白界面)
先来介绍一下蓝牙相关概念
蓝牙是一种无线技术标准,用于短距离内的数据交换。在 Android 设备上,蓝牙技术允许进行设备发现、配对、连接以及数据传输。它广泛应用于音频设备连接、数据同步、远程控制等多个领域。
在 Android Studio中 进行蓝牙开发,主要是通过调用 Android 平台提供的蓝牙 API,实现设备间的搜索、配对、连接以及数据传输功能。这包括在 AndroidManifest.xml 中声明必要的蓝牙权限,使用 BluetoothAdapter 和 BluetoothSocket(对于经典蓝牙)或 BluetoothGatt(对于BLE)等类进行编程,同时处理用户授权、兼容性问题、电量消耗和数据安全等挑战。
添加允许、权限
为了确保应用能够安全地访问设备上的特定功能或数据,而不会对其他应用或用户隐私造成潜在威胁,我们需要在 AndroidManifest.xml 中添加蓝牙相关权限。
点击处理
设置和配置一个 ListView 来显示蓝牙设备信息,并处理 ListView 的点击事件。
为打开、关闭蓝牙、获取蓝牙状态按钮添加点击效果
为按钮设置点击监听器,用于更新显示已绑定蓝牙设备列表的UI。在点击事件中,它首先尝试获取必要的权限,然后清空现有设备列表,并查询所有已绑定的蓝牙设备。对于每个设备,根据其绑定状态,将设备名称和地址添加到列表中,并立即通知适配器数据已更改。
打开关闭蓝牙
BlueToothController()
方法:用于初始化蓝牙适配器 (BluetoothAdapter
)。它调用 BluetoothAdapter.getDefaultAdapter()
来获取当前设备的蓝牙适配器实例,并将其存储在成员变量 BtAdapter
中,这是后续所有蓝牙操作的基础。
turnOnBuleTooth()
方法:用于打开蓝牙。它首先检查蓝牙是否已启用,如果没有,则通过 Intent
(BluetoothAdapter.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