最近项目开发中蓝牙打印机需要用到蓝牙,所以在这里对蓝牙知识进行一个梳理和总结。
在使用蓝牙时有几个需要注意在这里新提出来 :
1: 权限 :前面两个蓝牙权限大家都会记住,如果你出现下面这个异常:
因为。。。6.0系统上的蓝牙服务要和位置服务都打开才能搜索!
<!-- 允许程序连接到已配对的蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!-- 允许程序发现和配对蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 允许程序发现和配对蓝牙设备 -->
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!--地理位置-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
PS(6.0以上版本手机系统都需要在代码中请求权限,这个是我平时比较经常用的注解式权限访问库大家可以参考一下
传送门)
2: 蓝牙传输数据前需要先进行配对,配对成功,才能传输数据。已经配对蓝牙,不代表对方的蓝牙还开启。手机会帮你记住配对过的蓝牙。
3.切记扫描完蓝牙一定要关闭蓝牙搜索。
一、
BluetoothAdapter类介绍
概述:代表本地蓝牙适配器设备,BluetoothAdapter类让用户能执行基本的蓝牙任务
有如下功能:
1、开关蓝牙设备
2、扫描蓝牙设备
3、设置/获取蓝牙状态信息,例如:蓝牙状态值、蓝牙Name、蓝牙Mac地址等;
1、BluetoothAdapter STATE 状态值 , 即开关状态
PS(这个状态可以用在监听蓝牙状态发生变化时系统会发送广播来我们可以根据系统发送的广播 来做处理)
int
STATE_OFF
蓝牙已经关闭
int
STATE_ON
蓝牙已经打开
int
STATE_TURNING_OFF
蓝牙处于关闭过程中 ,关闭ing
int
STATE_TURNING_ON
蓝牙处于打开过程中 ,打开ing
蓝牙关闭过程:
STATE_TURNING_OFF======》
STATE_OFF
蓝牙打开过程:
STATE_TURNING_ON======》STATE_ON
2、
BluetoothAdapter
SCAN_MOD状态值 ,即扫描状态
5、 关闭蓝牙
首先说明,可以扫描其他设备的,当然它同时能被其他蓝牙设备扫码。
int
SCAN_MODE_CONNECTABLE
表明该蓝牙可以扫描其他蓝牙设备
int
SCAN_MODE_CONNECTABLE_DISCOVERABLE
表明该蓝牙设备同时可以扫码其他蓝牙设备,并且可以被其他蓝牙设备扫描到。
int
SCAN_MODE_NONE
: 该蓝牙不能扫描以及被扫描。
3、获得蓝牙适配器实例
public static synchronized
BluetoothAdapter
getDefaultAdapter ()
功能:获得本设备的蓝牙适配器实例。
返回值:如果设备具备蓝牙功能,返回
BluetoothAdapter
实例;否则,返回null对象。
4、打开蓝牙(两种方法)
a、强制打开:
boolean result = mBluetoothAdapter.enable();
b、通过一个intent:
6. if (!mBluetoothAdapter.isEnabled()) //未打开蓝牙,才需要打开蓝牙
7. {
8. Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
9. startActivityForResult(intent, REQUEST_OPEN_BT_CODE); //自己定义的code,结果码
10. //会以Dialog样式显示一个Activity , 我们可以在onActivityResult()方法去处理返回值
11. }
5、 关闭蓝牙
直接调用API 函数即disable()即可。
public boolean disable ()
功能:关闭蓝牙设备。
返回值:该函数会立即返回。
true 表示关闭操作成功
false 表示蓝牙操作失败 , ①、当前蓝牙已经关闭 ; ②、其他一些异常情况
6、扫描蓝牙设备
ps(只要有开启蓝牙扫描startDiscovery ()一定要关闭 cancelDiscovery)
public boolean startDiscovery ()
功能: 扫描蓝牙设备
注意: 如果蓝牙没有开启,该方法会返回false ,即不会开始扫描过程。
public boolean cancelDiscovery ()
功能: 取消扫描过程。
注意: 如果蓝牙没有开启,该方法会返回false。
public boolean isDiscovering ()
功能: 是否正在处于扫描过程中。
注意: 如果蓝牙没有开启,该方法会返回false。
7、 获取蓝牙相关信息
public String getName ()
功能:获取蓝牙设备Name
public String getAddress ()
功能:获取蓝牙设备的硬件地址(MAC地址),例如:00:11:22:AA:BB:CC
public boolean setName (String name)
功能:设置蓝牙设备的Name,
public
Set<BluetoothDevice>
getBondedDevices ()
功能:获取与本机蓝牙所有绑定的远程蓝牙信息,以
BluetoothDevice
类实例(稍后讲到)返回。
注意:如果蓝牙为开启,该函数会返回一个空集合 。
public static boolean checkBluetoothAddress (String address)
功能: 验证蓝牙设备MAC地址是否有效。所有设备地址的英文字母必须大写,48位,形如:00:43:A8:23:10:F1 。
返回值: true 设备地址有效
false 设备地址无效
public
BluetoothDevice
getRemoteDevice (String address)
功能:以给定的MAC地址去创建一个 BluetoothDevice 类实例(代表远程蓝牙实例)。即使该蓝牙地址不可见,也会产生
一个BluetoothDevice 类实例。
返回:BluetoothDevice 类实例 。注意,如果该蓝牙设备MAC地址不能被识别,其蓝牙Name为null。
异常:如果MAC address无效,抛出
IllegalArgumentException
。
8、蓝牙相关广播
Action值
ACTION_STATE_CHANGED
蓝牙状态值发生改变
ACTION_SCAN_MODE_CHANGED
蓝牙扫描状态(SCAN_MODE)发生改变
ACTION_DISCOVERY_STARTED
蓝牙扫描过程开始
ACTION_DISCOVERY_FINISHED
蓝牙扫描过程结束
ACTION_LOCAL_NAME_CHANGED
蓝牙设备Name发生改变
ACTION_REQUEST_DISCOVERABLE
请求用户选择是否使该蓝牙能被扫描
PS:如果蓝牙没有开启,用户点击确定后,会首先开启蓝牙,继而设置蓝牙能被扫描。
ACTION_REQUEST_ENABLE
请求用户选择是否打开蓝牙
ACTION_FOUND
(该常量字段位于BluetoothDevice类中,稍后讲到)
说明:蓝牙扫描时,扫描到任一远程蓝牙设备时,会发送此广播。
下面是我用的蓝牙工具类封装:
public class BtUtil {
/**
* 判断蓝牙是否打开
*
* @return boolean
*/
public static boolean isOpen(BluetoothAdapter adapter) {
if (null != adapter) {
return adapter.isEnabled();
}
return false;
}
/**
* 搜索蓝牙设备
*/
public static void searchDevices(BluetoothAdapter adapter) {
// 寻找蓝牙设备,android会将查找到的设备以广播形式发出去
if (null != adapter) {
adapter.startDiscovery();
}
}
/**
* 取消搜索蓝牙设备
*/
public static void cancelDiscovery(BluetoothAdapter adapter) {
if (null != adapter) {
adapter.cancelDiscovery();
}
}
/**
* register bluetooth receiver
*
* @param receiver bluetooth broadcast receiver
* @param activity activity
*/
public static void registerBluetoothReceiver(BroadcastReceiver receiver, Activity activity) {
if (null == receiver || null == activity) {
return;
}
IntentFilter intentFilter = new IntentFilter();
//start discovery
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
//finish discovery
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//bluetooth status change
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
//found device
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
//bond status change
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//pairing device
intentFilter.addAction("android.bluetooth.device.action.PAIRING_REQUEST");
activity.registerReceiver(receiver, intentFilter);
}
/**
* unregister bluetooth receiver
*
* @param receiver bluetooth broadcast receiver
* @param activity activity
*/
public static void unregisterBluetoothReceiver(BroadcastReceiver receiver, Activity activity) {
if (null == receiver || null == activity) {
return;
}
activity.unregisterReceiver(receiver);
}
}
更多关于BluetoothAdapter类的API介绍,请参考农民伯伯的博客:
二、 BluetoothDevice类介绍
该类就是关于远程蓝牙设备的一个描述。通过它可以和本地蓝牙设备---BluetoothAdapter连接通信。
1、
蓝牙绑定(Bound)状
态 , 即蓝牙设备是否与其他蓝牙绑定
int
BOND_BONDED
表明蓝牙已经绑定
int
BOND_BONDING
表明蓝牙正在绑定过程中 , bounding
int
BOND_NONE
表明没有绑定
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING://正在配对
Log.d("BlueToothTestActivity", "正在配对......");
break;
case BluetoothDevice.BOND_BONDED://配对结束
Log.d("BlueToothTestActivity", "完成配对");
connectBlt(device);
break;
case BluetoothDevice.BOND_NONE://取消配对/未配对
Log.d("BlueToothTestActivity", "取消配对");
default:
break;
}
更多关于BluetoothDevice类的更多介绍,请参考该农民伯伯的该篇博客: