从项目中封装出来的Demo, 先上效果图,图1是刚运行app搜索蓝牙设备的效果动图,图2是点击搜到的蓝牙设备列表项的发起连接效果图,图3是被点击的蓝牙设备收到的蓝牙配对请求效果图:
图1 图2 图3
Android中的无线传输蓝牙通信,先增加权限:
接下来正式进入代码部分,第一步是先获取系统默认的蓝牙适配器,打开蓝牙。BluetoothAdapter.getDefaultAdapter()这个方法是获取默认蓝牙适配器的唯一方法,获得适配器之后打开蓝牙却有2种方式,直接用方法enable()可以打开蓝牙,但是这个方法打开蓝牙不会弹出提示,实际的开发场景多会需要UI交互提示用户,所以多用Intent的方式去打开蓝牙,图2的效果便是如此:
/**
* 开启蓝牙且被发现
*
* enable()打开蓝牙,这个方法打开蓝牙不会弹出提示,更多的时候我们需要问下用户是否打开,一下这两行代码同样是打开蓝牙,不过会提示用户:
*
* Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
* enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
*/
private void enablebluetooth() {
//获取默认BluetoothAdapter,实际上,也只有这一种方法获取BluetoothAdapter
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
enable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivityForResult(enable, REQUEST_DISCOVERABLE);
}
然后在onActivityResult响应中,mBtAdapter.startDiscovery()开始搜索周围的蓝牙设备:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_DISCOVERABLE:
if (resultCode != Activity.RESULT_CANCELED) {
mBtAdapter.startDiscovery(); //startDiscovery()开始搜索,这是搜索的第一步, 使用BluetoothAdapter的startDiscovery()方法来搜索蓝牙设备
String blueToothName = SharedPreferencesUtils.getInst().getBlueToothAddress(context);
if (TextUtils.isEmpty(blueToothName)) {
} else {
device = mBtAdapter.getRemoteDevice(blueToothName);
if (device != null) {
if (client == null || !client.isConnect()) {
client = BlueToothTool.getInstance();
client.setDevice(device);
client.setMhandler(handler);
client.connect();
newBlueToothConnect = true;
}
} else
mBtAdapter.startDiscovery();
}
}
break;
default:
break;
}
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
System.out.println("----------------------------------" + msg.what + "----------------------------------");
switch (msg.what) {
case BlueToothTool.CONNECT_FAILED:
newBlueToothConnect = false;
break;
case BlueToothTool.CONNECT_SUCCESS:
STContext.getInst().bluetoothDevice = device;
SharedPreferencesUtils.getInst().setBlueToothAddress(device.getAddress(), context);
isFindBlueToothDevice = false;
break;
case BlueToothTool.READ_FAILED:
break;
case BlueToothTool.WRITE_FAILED:
//
break;
case BlueToothTool.DATA:
if (msg.obj != null && msg.obj.toString().length() > 10) {
STContext.getInst().bluetoothDevice = device;
newBlueToothConnect = false;
SharedPreferencesUtils.getInst().setBlueToothAddress(device.getAddress(), context);
}
break;
}
}
};
接着注册蓝牙寻找相关的广播,并在广播接受器对相应的广播编写相关的逻辑
/**
* 注册广播事件
*
* BluetoothDevice.ACTION_FOUND:搜索到
* ACTION_DISCOVERY_FINISHED:搜索结束
* ACTION_FOUND:找到设备,这个Intent中包含两个extra fields:EXTRA_DEVICE和EXTRA_CLASS,分别包含BluetooDevice和BluetoothClass。
* 我们可以自己注册相应的BroadcastReceiver来接收响应的广播,以便实现某些功能
*/
@Override
public void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
receiver = new BluetoothReceiver();
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
}
/**
* 广播接收器
*/
private class BluetoothReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//getAddress()获取本地蓝牙地址 getName()获取本地蓝牙名称
if (!TextUtils.isEmpty(device.getName()) && !TextUtils.equals("null", device.getName())) {
String str = device.getName() + "|" + device.getAddress();
if (deviceList.indexOf(str) == -1)// 防止重复添加
deviceList.add(str); // 获取设备名称和mac地址
if (multiTypeAdapter != null) {
multiTypeAdapter.notifyItemInserted(deviceList.size());
rl_system_message.scrollToPosition(deviceList.size());
}
}
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
if (findCount < 2) {
mBtAdapter.cancelDiscovery();
findCount++;
pro_loading.setVisibility(View.GONE);
txt_state.setText("检测完毕");
}
}
}
}
点击想连接的蓝牙设备后,执行连接方法,其中核心是BluetoothServerSocket蓝牙连接对象:
/**
* 开辟连接线程任务
*/
public void connect() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
BluetoothSocket tmp = null;
Method method;
activeDisconnect = false;
try {
method = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
tmp = (BluetoothSocket) method.invoke(device, 1);
} catch (Exception e) {
System.out.println("----------------------------------" + "11111111111111111111" + "----------------------------------");
setState(CONNECT_FAILED);
Log.e("TAG", e.toString());
}
socket = tmp;
try {
socket.connect();
isConnect = true;
if (nullDataCount == 0) {
setState(CONNECT_SUCCESS);
} else {
nullDataCount = 0;
reconnectCount++;
}
Readtask readtask = new Readtask(); //连接成功后开启读取数据的线程
readtask.start();
} catch (Exception e) {
System.out.println("----------------------------------" + "2222222222222222222" + "----------------------------------");
System.out.println("----------------------------------" + e.getMessage() + "----------------------------------");
if (!activeDisconnect){
setState(CONNECT_FAILED);
isConnect = false;
}
Log.e("TAG", e.toString());
}
}
});
new Thread(thread).start();
}
Demo已上传:https://download.csdn.net/download/crystal_xing/10878789