Android开发系列——实战篇12:蓝牙开发(一)(设备操作篇)

蓝牙是Android开发以及各种嵌入式系统相互通信的重要工具,本文开始深入理解Android开发中蓝牙的原理与操作方式。

目录

  • 一、蓝牙简介
  • 二、蓝牙控制
    • 1.蓝牙适配概述
    • 2.初始化蓝牙适配器
    • 3.启用蓝牙
  • 三、小结

一、蓝牙简介

蓝牙是一种短距离无线通信技术,我们比较熟知的移动端设备短距离通信技术有NFC、红外与蓝牙。它们都是无线技术标准,但是实际的应用场景各不相同。
NFC主要用于操作简单、即时响应的刷卡、红外主要用于需要按键控制、价格低廉的家电遥控,而蓝牙主要用于两部设备之间复杂且大量的数据传输。
下面这张图比较了三者技术参数之间的差别:
Android开发系列——实战篇12:蓝牙开发(一)(设备操作篇)_第1张图片
(注:图中蓝牙是以蓝牙2.0等旧代版本蓝牙为例,BLE——蓝牙4.0及以上新版本蓝牙通信距离<=100m,最大传输速度达3M/S,连接建立时间2s。)

二、蓝牙控制

1.蓝牙适配概述

蓝牙的基本使用流程为:

  • 初始化蓝牙
  • 打开蓝牙
  • 在范围内搜索可用蓝牙设备
  • 连接并绑定设备
  • 建立双端通信通道
  • 进行设备间数据的传输
  • 关闭蓝牙

蓝牙的操作分为很多步骤,大体上分为蓝牙设备的控制设备间数据的传输两大部分。这里先介绍蓝牙设备的控制步骤,包括初始化蓝牙,启用蓝牙,查找扫描设备,连接与绑定设备

Android提供了蓝牙模块的管理工具BluetoothAdapter(蓝牙适配器)。

BluetoothAdapter类的一些常用方法说明:

  • getDefaultAdapter:获取默认的蓝牙适配器,该方法为静态方法。(一个设备只有一个蓝牙适配器)
  • getState:获取蓝牙的开关状态。STATE_ON表示已开启,STATE_TURNING_ON表示正在开启,STATE_OFF表示已关闭,STATE_TURNING_OFF表示正在关闭。
  • enable:启用蓝牙功能。
  • disable:禁用蓝牙功能。
  • isEnable:判断蓝牙功能是否已启用。返回True表示已启用,返回false表示未启用。
  • getBondedDevices:获取已配对的设备集合。
  • getRomoteDevices:根据设备地址获取远程的设备对象。
  • startDiscovery: 开始搜索周围的蓝牙设备。
  • cancelDiscovery:取消搜索周围的蓝牙设备。
  • isDiscovering:判断是否正在搜索周围的蓝牙设备。

虽然BluetoothAdapter名叫蓝牙适配器,但它实际上干了蓝牙管理器的活。因为Android从4.3开始引入了正牌的蓝牙管理器BluetoothManager,调用BluetoothManager对象的getAdapter也可获得蓝牙适配器。(注意是4.3是Android版本。)

Android4.3对蓝牙的增强补充,主要是为了支持最新的BLE(蓝牙低功耗功能),BLE对应的是蓝牙4.0及以上的版本。
(注意这里的4.0是蓝牙版本。)

注:BLE是Bluetooth Low Energy,蓝牙低功耗。平时处于“非连接”状态,仅知晓对方。传输时开启线路,传输完毕迅速关闭线路。因此BLE与以前的蓝牙版本相比,更省电,连接速度更快,传输距离更远。

2.初始化蓝牙适配器

首先是对蓝牙适配器的初始化,在使用蓝牙之前,需要在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();
        }

    }

3.启用蓝牙

Android中提供了enable方法直接开启蓝牙,但是这样并不能让本地蓝牙本扫描到。需要通过弹窗的方式进行允许扫描权限的选择。
Android开发系列——实战篇12:蓝牙开发(一)(设备操作篇)_第2张图片

需要重写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中如果需要启用蓝牙,需要进行弹窗选择进行权限的确认,不然的话直接启用的蓝牙无法被扫描到。

你可能感兴趣的:(Android开发系列)