在使用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的保护机制,在流结束,连接结束时就需要在此及时关闭所有的连接。