首先要说的是如果程序想操作蓝牙,必须拥有两个权限,最好先写到清单文件中
<!-- 声明蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 允许程序发现和配对蓝牙设备 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
接下来咱们说说蓝牙的最具跨时代的版本吧,蓝牙4.0,蓝牙4.0是2012年最新蓝牙版本,是3.0的升级版本;较3.0版本更省电、成本低、3毫秒低延迟、超长有效连接距离、AES-128加密等;通常用在蓝牙耳机、蓝牙音箱等设备上。对程序影响最大的就数蓝牙4.0版本和咱们android4.3了,因为在android4.3之前的版本,android系统是不支持蓝牙4.0的所以有了这个分水岭,在开发的时候要特别的注意了。
1、蓝牙的打开和关闭
通过BluetoothAdapter类来控制本地蓝牙设备。该类代表运行应用程序的Android设备。为了访问默认的bluetooth adapter ,需要调用getDefaultAdapter ,一些Android设备有多个BluetoothAdapter ,但目前只可以访问默认设备。
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
BluetoothAdapter提供了用于读取并设置本地蓝牙硬件的属性的方法,使用isEnabled方法确认设备已经启动,然后使用getName和getAddress方法分别访问BluetoothAdapter的“友好”的名称(由用户设置的、用于标识特定设备的任意字符串)以及硬件地址。
// 蓝牙打开
bluetooth.enable();
// 蓝牙关闭
bluetooth.disable();
如何友好的向用户展示这一个过程呢?建议用以下方式提示用户,让用户自己做选择
if (!bluetooth.isEnabled()) {
//蓝牙未启用,提示用户打开它
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}else{
//蓝牙已经开启,关闭蓝牙或者做其他的操作
}
这样在onActivityResult中就能得到用户的选择了
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_CANCELED) {
Log.d(TAG, "requestCode = 1 RESULT_CANCELED ");
}else if (resultCode == RESULT_OK) {
Log.d(TAG, "requestCode = 1 RESULT_OK ");
}
}
}
2、设置蓝牙的可发现性
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200); //第二个参数是本机蓝牙被发现的时间,系统默认范围[1-300]秒,系统默认120秒
startActivityForResult(intent, 2);
同样的,在onActivityResult中加入此判断,如果用户取消了,在这里做处理。
3、扫描周边设备
private ArrayList<BluetoothDevice> devicesList = new ArrayList<BluetoothDevice>();
public void discoveryDevice() {
IntentFilter intent = new IntentFilter();
intent.addAction(BluetoothDevice.ACTION_FOUND);
intent.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(searchDevices, intent);
if (bluetooth.isEnabled() && !bluetooth.isDiscovering()) {
devicesList.clear();
bluetooth.startDiscovery();
}
}
private BroadcastReceiver searchDevices = new BroadcastReceiver() {
@SuppressLint("UseSparseArrays")
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devicesList.add(device);
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
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", "完成配对");
connect(device);// 连接设备
break;
case BluetoothDevice.BOND_NONE:
Log.d("BlueToothTestActivity", "取消配对");
default:
break;
}
}
}
};
将扫描到的设备都存在一个列表中,这里也写了点绑定设备的代码,接下来要用。
4、绑定/连接设备
public void connectDevice(int index) {
if (bluetooth.isDiscovering())
bluetooth.cancelDiscovery();
BluetoothDevice remoteDevice = devicesList.get(index);
try {
if (remoteDevice.getBondState() == BluetoothDevice.BOND_NONE) {
// 利用反射方法调用BluetoothDevice.createBond(BluetoothDevice remoteDevice);
Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
Log.d("BlueToothTestActivity", "开始配对");
createBondMethod.invoke(remoteDevice);
} else if (remoteDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
connect(remoteDevice);
}
} catch (Exception e) {
e.printStackTrace();
}
}
在3的代码中,如果绑定成功将直接连接设备,方法如下:
private void connect(BluetoothDevice btDev) {
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//SPP协议 蓝牙串行端口基于SPP协议(Serial Port Profile),能在蓝牙设备之间创建串口进行数据传输。
try {
btSocket = btDev.createRfcommSocketToServiceRecord(uuid);
btSocket.connect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
关于UUID的相关资料,可以问问度娘。