Android蓝牙 - 经典蓝牙BT

一、蓝牙发展历程

蓝牙(Bluetooth):是一种无线技术标准,可实现设备间短距离数据交换。 蓝牙可以以一定的周期发送广播,手机端接收到广播后,解析广播包,可做设备识别、配对,事件通知以及指令控制等。低精度定位根据设备的信号强度,可以估算出大概方位和距离。

蓝牙发展至今经历了多个版本的更新,其中,将1.x~3.0之间的版本称之为经典蓝牙,4.x开始的蓝牙称之为低功耗蓝牙,也就是蓝牙BLE。

根据应用、协议类型等,可以对蓝牙进行以下分类:
image.png

二、经典蓝牙API

1、BluetoothAdapter:代表了移动设备的本地的蓝牙适配器, 通过该蓝牙适配器可以对蓝牙进行基本操作, 例如 : 启动设备发现,获取已配对设备,通过mac蓝牙地址获取蓝牙设备等。

  • enable():打开蓝牙,需要 BLUETOOTH_ADMIN权限。
  • disable():关闭蓝牙,需要 BLUETOOTH_ADMIN权限。
  • checkBluetoothAddress(String address):验证蓝牙设备MAC地址是否有效。
  • getAddress():获取本地蓝牙适配器的硬件地址(MAC地址)
  • getBondedDevices():获取与本机蓝牙所有绑定的远程蓝牙信息。
  • getName():获取本地蓝牙适配器的蓝牙名称。
  • setName(String name):设置本地蓝牙适配器的蓝牙名称。
  • isEnabled():判断当前蓝牙适配器是否打开。
  • isDiscovering():判断蓝牙适配器是否正在处于扫描过程中。
  • startDiscovery():开始扫描周边蓝牙设备。
  • cancelDiscovery():取消蓝牙搜索操作。
  • getScanMode():获取本地蓝牙适配器的当前蓝牙扫描模式。

蓝牙扫描模式:
SCAN_MODE_NONE: 该设备不能扫描以及被扫描。
SCAN_MODE_CONNECTABLE:该设备可以扫描其他蓝牙设备。
SCAN_MODE_CONNECTABLE_DISCOVERABLE:该设备既可以扫描其他设备,也可以被其他设备扫描发现。

  • getState():获取本地蓝牙适配器的当前状态。

蓝牙适配器状态:
STATE_OFF:表示本地蓝牙适配器已关闭。
STATE_TURNING_ON:表示本地蓝牙适配器正在打开。
STATE_ON:表示本地蓝牙适配器已开启,并可供使用。
STATE_TURNING_OFF:表示本地蓝牙适配器正在关闭。

  • getRemoteDevice(String address):获取给定蓝牙硬件地址的BluetoothDevice对象。

如果address中的MAC无效无效,将抛出IllegalArgumentException异常。

  • listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid):创建不安全的蓝牙服务套接字。
  • listenUsingRfcommWithServiceRecord(String name, UUID uuid):创建一个正在监听的安全的带有服务记录的无线射频通信(RFCOMM)蓝牙端口。

2、BluetoothDevice:代表了一个远程的蓝牙设备, 通过这个类可以查询远程设备的物理地址, 名称, 连接状态等信息。这个类实际上只是一个蓝牙硬件地址的简单包装,这个类的对象是不可变的。对这个类的操作, 会执行在远程蓝牙设备的硬件上。

  • getName():获取远程蓝牙设备的蓝牙名称。
  • getAddress():获取远程蓝牙设备的硬件地址。
  • createBond():开始与远程蓝牙设备的绑定过程。
  • getBondState():获取远程蓝牙设备的绑定状态。

蓝牙绑定状态:
BOND_NONE:远程设备未绑定。
BOND_BONDING:正在与远程设备进行绑定。
BOND_BONDED:远程设备已绑定。

  • createInsecureRfcommSocketToServiceRecord(UUID uuid):创建不安全的蓝牙套接字。
  • createRfcommSocketToServiceRecord(UUID uuid):创建安全的蓝牙套接字。

3、BluetoothServerSocket:侦听蓝牙服务套接字。使用BluetoothServerSocket可以创建一个监听服务端口, 使用accept方法阻塞, 当该方法监测到连接的时候, 就会返回一个BluetoothSocket对象来管理这个连接。BluetoothServerSocket是线程安全的,close方法始终会立即中止正在进行的操作并关闭蓝牙服务套接字。需要BLUETOOTH权限。

  • accept():阻塞直到建立连接,成功连接时连接的BluetoothSocket对象。
  • accept(int timeout):阻塞直到建立连接或超时,成功连接时连接的BluetoothSocket对象。
  • close():关闭该监听服务端口,并释放所有关联的资源。

4、BluetoothSocket:蓝牙套接口。在服务器端,使用BluetoothServerSocket创建侦听服务器套接字。当连接被BluetoothServerSocket接受时,它将返回一个新的BluetoothSocket来管理连接。 在客户端,使用单个BluetoothSocket来启动连接并管理连接。BluetoothSocket是线程安全的,close方法始终会立即中止正在进行的操作并关闭套接字。需要BLUETOOTH权限。

  • connect():尝试连接到远程蓝牙服务器。
  • isConnected():获取此套接字的连接状态,即是否与远程蓝牙服务连接。
  • getRemoteDevice():获取此套接字连接的远程蓝牙设备。
  • getInputStream():获取与此套接字关联的输入流。

即使套接字尚未连接,输入流也会返回,但对该流的操作将抛出IOException异常,直到关联的套接字连接。

  • getOutputStream():获取与此套接字关联的输出流。

即使套接字尚未连接,输出流也会返回,但对该流的操作将抛出IOException异常,直到关联的套接字连接。

  • close():关闭此流并释放与其关联的所有系统资源。如果流已经关闭,则调用此方法不起作用。

三、经典蓝牙开发

1、在工程清单文件AndroidManifest.xml中添加权限:

<!--如果使用了BLUETOOTH_ADMIN权限,那么必须使用BLUETOOTH权限-->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

<!--android6.0后需要搜索周边蓝牙设备,需要添加以下两个权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<!--要求设备硬件必须支持蓝牙-->
<uses-feature android:name="android.hardware.bluetooth" android:required="true"/>

2、获取本地蓝牙适配器
BluetoothAdapter有两种方式获取,方式二要求Android4.3以上才可以用,建议使用方式一,比较通用。

//第一种方式
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

//第二种方式
BluetoothManager manager = (BluetoothManager) Context.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = manager.getAdapter();

3、打开蓝牙
方式一:通过Intent来向用户弹框请求打开蓝牙,可以重写onActivityResult来监听打开蓝牙的请求结果.

public void openBluetooth(){
   
    if (mBluetoothAdapter==null) {
   
		//自定义方法,用来往TextView上添加提示信息
        showTip("当前设备不支持蓝牙功能!");
        return;
    }

    if (mBluetoothAdapter.isEnabled()) {
   
        showTip("蓝牙已打开");
        return;
    }

    Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(intent,GlobalDef.REQ_CODE_OPEN_BT);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
   
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode==GlobalDef.REQ_CODE_OPEN_BT) {
   
        if (resultCode == Activity.RESULT_OK) {
   
            showTip("蓝牙打开成功");
        } else {
   
            showTip("蓝牙打开失败");
        }
    }
}

方式二:通过enable方法静默打开蓝牙,无需用户同意(部分Android系统使用该方法依然会弹框提示,向用户请求打开蓝牙)

mBluetoothAdapter.enable();

4、关闭蓝牙
关闭蓝牙,无需用户同意(部分Android系统使用该方法依然会弹框提示)

mBluetoothAdapter.disable();

5、允许蓝牙可被发现
如果开发的外围设备如音箱,需要被中心设备发现扫描到,需要该功能。有两种实现方式:
方式一:通过Intent方式向用户请求允许蓝牙被搜索。如果蓝牙没有开启,用户点击确定后,会首先开启蓝牙,继而设置蓝牙能被扫描。

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//设置蓝牙可见性的时间,默认持续时间为120秒,每个请求的最长持续时间上限为300秒
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
startActivity(intent);

方式二:通过反射的方式来设置蓝牙可见性,且不会出现弹框,如果蓝牙没有开启,通过此方式并不会直接打开蓝牙。

/**
 * 设置蓝牙可见
 * @param adapter
 * @param timeout 超时为0时,永久可见
 */
public static void setDiscoverableTimeout(BluetoothAdapter adapter, int timeout) {
   
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    try {
   
        Method setDiscoverableTimeout = BluetoothAdapter.class.getMethod("setDiscoverableTimeout", int.class);
        setDiscover
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值