今天记录一下蓝牙的简单用法。按照如下各个步骤进行。
在AndroidManifest.xml中进行如下权限的配置
通过如下代码初始化蓝牙适配器。
private BluetoothAdapter mBluetooth;
/**
* 初始化蓝牙适配器
*/
private void initBluetooth(){
//Android从4.3开始增加支持BLE技术(即蓝牙4.0以上版本)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
//从系统服务中获取蓝牙管理器
BluetoothManager bm = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetooth = bm.getAdapter();
}else{
//获取系统默认的蓝牙适配器
mBluetooth = BluetoothAdapter.getDefaultAdapter();
}
if (mBluetooth == null){
ToastUtil.toastWord(this,"本机未找到蓝牙功能");
}
}
首先我们需要声明一个回调变量
private int mOpenCode = 0x01;
接着我们要进行弹框提醒用户,是否允许其他设备检测到当前手机
private void startBluetooth(){
//弹出是否允许扫描蓝牙设备的选择对话框
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(intent,mOpenCode);
}
在onActivityResult中进行判断用户是点击的确认还是取消
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == mOpenCode){//来自允许蓝牙扫描的对话框
if (resultCode == 120){
ToastUtil.toastWord(this,"允许本地蓝牙被附近的其他蓝牙设备发现");
//延迟50毫秒后启动蓝牙设备的刷新任务
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO: 2021/4/1 执行蓝牙搜索
}
},50);
}else{
ToastUtil.toastWord(this,"不允许蓝牙被附近的其他蓝牙设备发现");
}
}
}
这里我尝试了vivo z1和小米CC以及一部华为平板,对于允许蓝牙开启的返回值均为120,其他机型的情况可能还需要进一步进行测试。书中说的是RESULT_OK,即-1的时候是成功。
首先我们要开启搜索周边蓝牙设备的方法
private void beginDiscovery(){
//如果当前不是正在搜索,则开始新的搜索任务
if (!mBluetooth.isDiscovering()){
mBluetooth.startDiscovery();//开始扫描周围的蓝牙设备
}
}
接着我们在刚刚打开蓝牙功能回调的成功回调中,执行该方法。onActivityResult方法修改如下
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == mOpenCode){//来自允许蓝牙扫描的对话框
if (resultCode == 120){
ToastUtil.toastWord(this,"允许本地蓝牙被附近的其他蓝牙设备发现");
//延迟50毫秒后启动蓝牙设备的刷新任务
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
beginDiscovery();
}
},50);
}else{
ToastUtil.toastWord(this,"不允许蓝牙被附近的其他蓝牙设备发现");
}
}
}
由于我们的蓝牙搜索是异步的,系统通过广播返回搜索到的设备,所以我们要进行广播的注册监听,代码如下
@Override
protected void onStart() {
super.onStart();
//需要过滤多个动作,则调用IntentFilter对象的addAction添加新动作
IntentFilter discoveryFilter = new IntentFilter();
discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
//注册蓝牙设备搜索的广播接收器
registerReceiver(discoveryReceiver,discoveryFilter);
}
@Override
protected void onStop() {
super.onStop();
//注销蓝牙设备搜索的广播接收器
unregisterReceiver(discoveryReceiver);
}
private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//获得已经搜索到的蓝牙设备
if (action.equals(BluetoothDevice.ACTION_FOUND)){//发现新的蓝牙设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
listBluetooth.add(device);
mAdapter.notifyDataSetChanged();
}
}
};
我们写了一个列表,并且显示了所有设备,这里就不写了,基础操作。重点是显示的时候注意
String name = "";
if (NullUtil.isStringEmpty(list.get(position).getName())){
name = list.get(position).getAddress();
}else{
name = list.get(position).getName();
}
mineHolder.tv.setText(name);
可以看到,我们进行了一个判断,因为有些设备getName获取不到它的名称,所以我们显示的是地址。
配对操作由BluetoothDevice类管理,BluetoothDevice类的常用方法如下:
配对代码如下:
首先,我们点击列表对应设备时调用方法
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
if (listBluetooth.get(position).getBondState() == BluetoothDevice.BOND_NONE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
listBluetooth.get(position).createBond();
}
}
}
});
配对结果的回调同样是通过广播异步返回的,所以我们修改onStart方法如下
@Override
protected void onStart() {
super.onStart();
//需要过滤多个动作,则调用IntentFilter对象的addAction添加新动作
IntentFilter discoveryFilter = new IntentFilter();
discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
//增加配对状态的变更动作
discoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//注册蓝牙设备搜索的广播接收器
registerReceiver(discoveryReceiver,discoveryFilter);
}
接着是我们的广播接收者
private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//获得已经搜索到的蓝牙设备
if (action.equals(BluetoothDevice.ACTION_FOUND)){//发现新的蓝牙设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
listBluetooth.add(device);
mAdapter.notifyDataSetChanged();
}else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//更新蓝牙设备的配对状态
if (device.getBondState() == BluetoothDevice.BOND_BONDING){
tv_state.setText("正在配对:"+device.getName());
}else if (device.getBondState() == BluetoothDevice.BOND_BONDED){
tv_state.setText("完成配对:"+device.getName());
}else if (device.getBondState() == BluetoothDevice.BOND_NONE){
tv_state.setText("取消配对:"+device.getName());
}
}
}
};
这样我们就实现了蓝牙的链接操作,并读取出蓝牙对应的状态。