Demo地址:Github 你省金币的选择~
由于蓝牙权限非危险权限,所以不需要再动态注册了。
BluetoothAdapter 用于基础的蓝牙操作,比如初始化搜索设备,对已配对设备进行检索等功能。
调用静态方法getDefaultAdapter()获取蓝牙适配器bluetoothadapter,如果返回为空,则表明此设备不支持蓝牙。
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//1.检测蓝牙支持
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
return;
}
isEnable()查看蓝牙是否打开
if (!mBluetoothAdapter.isEnabled()) {//若果没有打开,则开启蓝牙
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
/**
* 关闭蓝牙
*/
private void closeBlueTooth() {
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
}
}
BluetoothAdapter的getBondedDevices()方法可以获取已经预先配对好的蓝牙设备集合。
获取的device的name和adress信息放入一个List并通过ArrayAdapter展示在ListView上。
Set pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
pairString=device.getName() + "---" + device.getAddress();
list_pair_device.add(pairString);
}
lv_show_pair.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1,list_pair_device));
}
如果想让本地设备对其他设备蓝牙可见,调用startActivityForResult(Intent, int),传入ACTION_REQUEST_DISCOVERABLE
这会请求激活系统设置。默认激活120秒,时间可设,但是最长时间是300秒。0表示设备永远可见。在0~300外的数字会被设置为120秒。
//设置蓝牙可见Intent
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//设置蓝牙可见性的时间,方法本身规定最多可见300秒
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
调用BluetoothAdapter的startDiscovery()方法搜索设备。这个异步线程返回值=是否启动成功的boolean值。同时注意,不要在搜索过程中再次开启搜索。不要在与设备连接时启动搜索。搜索设备会减小连接的带宽。
if (mBluetoothAdapter.isDiscovering()) { //如果当前在搜索,就先取消搜索
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();//开启搜索
请求Discovery后,系统开始搜索蓝牙设备,在这个过程中,系统会发送以下三个广播:
ACTION_DISCOVERY_START:开始搜索
ACTION_DISCOVERY_FINISHED:搜索结束
ACTION_FOUND:找到设备,这个Intent中包含两个extra fields:EXTRA_DEVICE和EXTRA_CLASS,分别包含BluetooDevice和BluetoothClass。
我们通过自己配置广播接收器来实现Android蓝牙的搜索。
private final BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i(TAG, "onReceive: action=" + action);
if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
Log.i(TAG, "onReceive: 扫描开始");
} else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
Log.i(TAG, "onReceive: 扫描完成");
} else if (action.equals(BluetoothDevice.ACTION_FOUND)) {
Log.i(TAG, "onReceive: 发现周围设备广播");
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String name = bluetoothDevice.getName();
String address = bluetoothDevice.getAddress();
Log.i(TAG, "onReceive: name=" + name + " address=" + address);
bluetoothDevices.add(name + ":" + address);
arrayAdapter_serach.notifyDataSetChanged();
}
}
};
同时也要注册广播来监听蓝牙搜索状态。
IntentFilter filters = new IntentFilter();
filters.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filters.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filters.addAction(BluetoothDevice.ACTION_FOUND);
registerReceiver(receiver, filters);
蓝牙的基础功能大概也就这么多了,没有什么难点。
蓝牙的使用目的就在于设备间数据通信,把传统蓝牙的通信思路以及代码整理下。
思路很清晰,我们需要一个蓝牙服务器与蓝牙客户端来接收与发送消息。
如上所示,首先进行搜索设备。然后连接设备,通过BlueToothDevice的createRfcommSocketToServiceRecord()方法获得一个BluetoothSocket对象。注意在设备在进行设备的时候,需要关闭蓝牙搜索。
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
BluetoothSocketsocket =serverDevice.createRfcommSocketToServiceRecord(BluetoothTools.PRIVATE_UUID);
socket.connect();
如果这个过程不报错,然后通过这个socke对象就能会的输入输出流,从而进行读写操作。
this.outStream = new ObjectOutputStream(socket.getOutputStream());
this.inStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
同理,首先通过BluetoothAdapter的listenUsingRfcommWithServiceRecord方法创建一个BluetoothServiceSocket,其中第一个参数随便洗个字符串,第二个参数为UUID,需要保证服务和客户端UUID一致。然后通过其accept方法
获得一个BluetoothSocket,通过这个socket获取输入输出流进行数据通信。
public static final UUID PRIVATE_UUID = UUID.fromString("0f3561b9-bda5-4672-84ff-ab1f98e349b6");
serverSocket = adapter.listenUsingRfcommWithServiceRecord("Server", BluetoothTools.PRIVATE_UUID);
socket = serverSocket.accept();
基本过程如上所示。我找了个demo做了参考,修改了一下,可以直接使用。关于传统蓝牙的数据通信的Demo直接去看代码。