在使用android蓝牙功能之前,首先需要在项目里添加权限去打开蓝牙访问功能.
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
在添加权限后就可以使用蓝牙的相关功能啦。
首先在功能使用前,需要确认的是该手机是否具有蓝牙功能?蓝牙是否开启?以及蓝牙的开启及其关闭?
// 设备是否支持蓝牙
public static boolean isBluetoothSupported() {
return BluetoothAdapter.getDefaultAdapter() != null ? true : false;
}
// 蓝牙是否开启
public static boolean isBluetoothEnabled() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter
.getDefaultAdapter();
if (bluetoothAdapter != null) {
return bluetoothAdapter.isEnabled();
}
return false;
}
// 强制打开/关闭蓝牙
public static boolean turnOnBluetooth(boolean flag) {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter
.getDefaultAdapter();
if (bluetoothAdapter != null) {
if (flag)
return bluetoothAdapter.enable();
else
return bluetoothAdapter.disable();
}
return false;
}
最后的方法是根据传入的值来确定是关闭蓝牙还是开启蓝牙,但是如果在强制开启蓝牙失败后返回false,也就是该手机并不支持此方法打开蓝牙的话,我们就需要做好异常情况处理。使用Intent来时用户自己打开手机蓝牙。并在onActivity.....的返回方法中接收返回1的req,并在该返回值中判断Result_OK和Cancel就可以实现蓝牙打开功能了。
Intent mIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(mIntent, 1);
在之前蓝牙打开之后就可以使用我们的蓝牙模块了,BluetoothAdapter类是我们需要知道类的第一步。
mBtAdapter = BluetoothAdapter.getDefaultAdapter();得到我们需要的对象,从中找到我们需要的蓝牙独立对象。
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();得到曾经适配过的蓝牙对象集合可配对蓝牙都在BluetoothDevice对象中可以找到。
而搜索蓝牙集合需要用到广播机制。
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);开始扫描蓝牙
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);结束扫描蓝牙
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);蓝牙开关
filter.addAction(BluetoothAdapter.ACTION_BOND_STATE_CHANGED);状态改变(没有试过)
最后一个没有成功,可能是因为我接的蓝牙是公司的设备。
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Overridepublic void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
} else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
// 状态
int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
switch (blueState) {
case BluetoothAdapter.STATE_ON:
break;
case BluetoothAdapter.STATE_OFF:
break;
}
}
}
};
在此广播接收者中来寻找仔细需要的对应接收处理对象。
在注册仔细的蓝牙接收者之后,就需要来进行搜索蓝牙了。
mBtAdapter.startDiscovery();蓝牙扫描
mBtAdapter.cancelDiscovery();关闭蓝牙扫描
推荐使用这种方法来完整的蓝牙扫描功能:
// 搜索蓝牙
if (mBtAdapter.isDiscovering())
mBtAdapter.cancelDiscovery();
mBtAdapter.startDiscovery();
来确保安全的进行蓝牙扫描。开始之后就可以等待广播接收者中读取搜索到的蓝牙对象了。
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
}
}
所有的蓝牙数据都在BluetoothDevice中可以找到。
在此,就完成了蓝牙对象单独处理前的所有准备工作。
在得到蓝牙对象BluetoothDevice后,得到与之对应的Address:address = device.getAddress();,因为我是对蓝牙设备而不是手机中,所有更多连接请看这篇博客(这篇博客)。
在得到BluetoothDevice对象后,就要进行蓝牙连接,首先该过程是UI堵塞情况,需要开启线程异步处理,用到Handler机制。
mBluetoothAdapter.cancelDiscovery();
try {
if (mSocket == null)
mSocket = device.createRfcommSocketToServiceRecord(GlobalConstants.UUID_SPP);
mSocket.connect();
} catch (IOException e) {
e.printStackTrace();
try {
mSocket = (BluetoothSocket) device.getClass().getMethod("createRfcommSocket",
new Class[] { int.class }).invoke(device, 1);
mSocket.connect();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (InvocationTargetException e1) {
e1.printStackTrace();
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (mSocket.isConnected()) {
if (flag) {
// 蓝牙配对成功
}
} else {
if (flag) {
// 蓝牙配对失败
}
}
在此用到了一个UUID,这个UUID网络上有很多
UUID UUID_SPP = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
这是我使用的。
在很多博客中都推荐直接使用java反射来连接蓝牙,而此我分开来连接,确保完整性吧。此时我们就连接至该设备的蓝牙了数据都可以通过mSocket来获取,
mSocket.getInputStream();读流,使用循环来读取
mSocket.getOutputStream();写流
在最后我们要做好finally的保护机制,在流结束,连接结束时就需要在此及时关闭所有的连接。