蓝牙是Android开发以及各种嵌入式系统相互通信的重要工具,本文开始深入理解Android开发中蓝牙的原理与操作方式。
蓝牙是一种短距离无线通信技术,我们比较熟知的移动端设备短距离通信技术有NFC、红外与蓝牙。它们都是无线技术标准,但是实际的应用场景各不相同。
NFC主要用于操作简单、即时响应的刷卡、红外主要用于需要按键控制、价格低廉的家电遥控,而蓝牙主要用于两部设备之间复杂且大量的数据传输。
下面这张图比较了三者技术参数之间的差别:
(注:图中蓝牙是以蓝牙2.0等旧代版本蓝牙为例,BLE——蓝牙4.0及以上新版本蓝牙通信距离<=100m,最大传输速度达3M/S,连接建立时间2s。)
蓝牙的基本使用流程为:
蓝牙的操作分为很多步骤,大体上分为蓝牙设备的控制和设备间数据的传输两大部分。这里先介绍蓝牙设备的控制步骤,包括初始化蓝牙,启用蓝牙,查找扫描设备,连接与绑定设备。
Android提供了蓝牙模块的管理工具BluetoothAdapter(蓝牙适配器)。
BluetoothAdapter类的一些常用方法说明:
虽然BluetoothAdapter名叫蓝牙适配器,但它实际上干了蓝牙管理器的活。因为Android从4.3开始引入了正牌的蓝牙管理器BluetoothManager,调用BluetoothManager对象的getAdapter也可获得蓝牙适配器。(注意是4.3是Android版本。)
Android4.3对蓝牙的增强补充,主要是为了支持最新的BLE(蓝牙低功耗功能),BLE对应的是蓝牙4.0及以上的版本。
(注意这里的4.0是蓝牙版本。)
注:BLE是Bluetooth Low Energy,蓝牙低功耗。平时处于“非连接”状态,仅知晓对方。传输时开启线路,传输完毕迅速关闭线路。因此BLE与以前的蓝牙版本相比,更省电,连接速度更快,传输距离更远。
首先是对蓝牙适配器的初始化,在使用蓝牙之前,需要在AndroidManifest清单文件里声明相关的权限。
<!-- 蓝牙操作权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!-- 蓝牙配对权限-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
还有一些特殊情况的补充权限,可不加:
<!--仅在支持BLE(蓝牙4.0及以上)的设备上运行-->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<!--如果Android6.0蓝牙搜索不到设备,需要补充以下两个权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
然后对蓝牙进行初始化操作
//声明一个蓝牙适配器对象
private BluetoothAdapter mBluetooth;
//初始化蓝牙设备
public void initBluetooth(){
//如果是Android4.3以后支持BLE的版本
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
//从系统服务中获取蓝牙管理器对象
BluetoothManager bm = (BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
//调用getAdapter方法获取蓝牙适配器对象
mBluetooth = bm.getAdapter();
}else{
//获取系统默认的蓝牙适配器
mBluetooth = BluetoothAdapter.getDefaultAdapter();
}
if(mBluetooth == null){//如果返回值为空
Toast.makeText(this,"本机没有蓝牙功能",Toast.LENGTH_SHORT).show();
finish();
}
}
Android中提供了enable方法直接开启蓝牙,但是这样并不能让本地蓝牙本扫描到。需要通过弹窗的方式进行允许扫描权限的选择。
需要重写onActivituResult方法,接受来自弹窗的返回值,具体代码如下:
package com.example.bluetooth_2;
import androidx.appcompat.app.AppCompatActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
//声明一个蓝牙适配器对象
private BluetoothAdapter mBluetooth;
// 声明一个用于展示蓝牙设备的列表视图对象
private ListView lv_bluetooth;
//声明一个Switch对象
private Switch sw_bluetooth;
//创建一个变量存储弹窗选择返回代码
private int mOpenCode = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initBluetooth();
//将Switch视图与switch对象绑定
sw_bluetooth = findViewById(R.id.sw_bluetooth);
//列表视图与列表视图对象绑定
lv_bluetooth = findViewById(R.id.lv_bluetooth);
//设置转换开关监听函数
sw_bluetooth.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
if(isChecked){
sw_bluetooth.setText("开启");
//打开弹窗提示允许发现本设备
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(intent,mOpenCode);
}else{
sw_bluetooth.setText("关闭");
}
}
});
}
//重写onActivityResult函数用以接受弹窗选择返回结果并作出响应
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent intent){//接受由Intent传递过来的弹窗选择结果
super.onActivityResult(requestCode,resultCode,intent);
if(requestCode == mOpenCode){//来自允许蓝牙扫描的对话框
if(resultCode == RESULT_OK){
Toast.makeText(this,"允许本地蓝牙被其他设备发现",Toast.LENGTH_SHORT).show();
}
else if(resultCode == RESULT_CANCELED){
Toast.makeText(this,"不允许本地设备被其他蓝牙发现",Toast.LENGTH_SHORT).show();
}
}
}
//初始化蓝牙设备
public void initBluetooth(){
//如果是Android4.3以后支持BLE的版本
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
//从系统服务中获取蓝牙管理器对象
BluetoothManager bm = (BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
//调用getAdapter方法获取蓝牙适配器对象
mBluetooth = bm.getAdapter();
}else{
//获取系统默认的蓝牙适配器
mBluetooth = BluetoothAdapter.getDefaultAdapter();
}
if(mBluetooth == null){
Toast.makeText(this,"本机没有蓝牙功能",Toast.LENGTH_SHORT).show();
finish();
}
}
}
这样,打开选择按钮,进行弹窗权限的确认后就能开启蓝牙并被其他设备扫描到。
1.初始化蓝牙需要声明一些蓝牙权限。
2.对Android4.3以后支持BLE功能,以及BLE对应的蓝牙版本和特点需要了解,这样才初始化中可以根据不同的Android版本进行对应的选择。
3.Android中如果需要启用蓝牙,需要进行弹窗选择进行权限的确认,不然的话直接启用的蓝牙无法被扫描到。