安卓蓝牙实现即时通讯功能
本demo是《Android智能穿戴设备开发指南》书中的一块内容,实现了两台手机基于蓝牙进行即时通讯的功能。
demo演示如下:
结构图
主要代码
MainActivity:启动服务器和客户端界面
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.startServerBtn:
//打开服务器
Intent serverIntent = new Intent(MainActivity.this, ServerActivity.class);
serverIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(serverIntent);
break;
case R.id.startClientBtn:
//打开客户端
Intent clientIntent = new Intent(MainActivity.this, ClientActivity.class);
clientIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(clientIntent);
break;
}
}
ClientActivity
注册广播,开启服务(BluetoothClientService)
//广播接收器 private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothTools.ACTION_NOT_FOUND_SERVER.equals(action)) { //未发现设备 serversText.append("not found device\r\n"); } else if (BluetoothTools.ACTION_FOUND_DEVICE.equals(action)) { //获取到设备对象 BluetoothDevice device = (BluetoothDevice)intent.getExtras().get(BluetoothTools.DEVICE); deviceList.add(device); serversText.append(device.getName() + "\r\n"); } else if (BluetoothTools.ACTION_CONNECT_SUCCESS.equals(action)) { //连接成功 serversText.append("连接成功"); sendBtn.setEnabled(true); } else if (BluetoothTools.ACTION_DATA_TO_GAME.equals(action)) { //接收数据 TransmitBean data = (TransmitBean)intent.getExtras().getSerializable(BluetoothTools.DATA); String msg = "from remote " + new Date().toLocaleString() + " :\r\n" + data.getMsg() + "\r\n"; chatEditText.append(msg); } } };
#
//注册BoradcasrReceiver
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothTools.ACTION_NOT_FOUND_SERVER);
intentFilter.addAction(BluetoothTools.ACTION_FOUND_DEVICE);
intentFilter.addAction(BluetoothTools.ACTION_DATA_TO_GAME);
intentFilter.addAction(BluetoothTools.ACTION_CONNECT_SUCCESS);
registerReceiver(broadcastReceiver, intentFilter);
#
//开启后台service
Intent startService = new Intent(ClientActivity.this, BluetoothClientService.class);
startService(startService);
#
开始搜索蓝牙和连接第一个设备
startSearchBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //开始搜索 Intent startSearchIntent = new Intent(BluetoothTools.ACTION_START_DISCOVERY); sendBroadcast(startSearchIntent); } }); selectDeviceBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //选择第一个设备 Intent selectDeviceIntent = new Intent(BluetoothTools.ACTION_SELECTED_DEVICE); selectDeviceIntent.putExtra(BluetoothTools.DEVICE, deviceList.get(0)); sendBroadcast(selectDeviceIntent); } });
向服务器发送消息
sendBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //发送消息 if ("".equals(sendEditText.getText().toString().trim())) { Toast.makeText(ClientActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show(); } else { //发送消息 TransmitBean data = new TransmitBean(); data.setMsg(sendEditText.getText().toString()); Intent sendDataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_SERVICE); sendDataIntent.putExtra(BluetoothTools.DATA, data); sendBroadcast(sendDataIntent); } } });
ServerActivity
注册广播接收器
//广播接收器 private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothTools.ACTION_DATA_TO_GAME.equals(action)) { //接收数据 TransmitBean data = (TransmitBean) intent.getExtras().getSerializable(BluetoothTools.DATA); String msg = "from remote " + new Date().toLocaleString() + " :\r\n" + data.getMsg() + "\r\n"; msgEditText.append(msg); } else if (BluetoothTools.ACTION_CONNECT_SUCCESS.equals(action)) { //连接成功 serverStateTextView.setText("连接成功"); sendBtn.setEnabled(true); } } }; //注册BoradcasrReceiver IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothTools.ACTION_DATA_TO_GAME); intentFilter.addAction(BluetoothTools.ACTION_CONNECT_SUCCESS); registerReceiver(broadcastReceiver, intentFilter);
开启后台服务
//开启后台service Intent startService = new Intent(ServerActivity.this, BluetoothServerService.class); startService(startService);
向客户端发送消息
sendBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if ("".equals(sendMsgEditText.getText().toString().trim())) { Toast.makeText(ServerActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show(); } else { //发送消息 TransmitBean data = new TransmitBean(); data.setMsg(sendMsgEditText.getText().toString()); Intent sendDataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_SERVICE); sendDataIntent.putExtra(BluetoothTools.DATA, data); sendBroadcast(sendDataIntent); } } });
BluetoothClientService
/**
* 蓝牙模块客户端主控制Service
*/
public class BluetoothClientService extends Service {
//搜索到的远程设备集合
private List<BluetoothDevice> discoveredDevices = new ArrayList<BluetoothDevice>();
//蓝牙适配器
private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//蓝牙通讯线程
private BluetoothCommunThread communThread;
//控制信息广播的接收器
private BroadcastReceiver controlReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothTools.ACTION_START_DISCOVERY.equals(action)) {
//开始搜索
discoveredDevices.clear(); //清空存放设备的集合
bluetoothAdapter.enable(); //打开蓝牙
bluetoothAdapter.startDiscovery(); //开始搜索
} else if (BluetoothTools.ACTION_SELECTED_DEVICE.equals(action)) {
//选择了连接的服务器设备
BluetoothDevice device = (BluetoothDevice)intent.getExtras().get(BluetoothTools.DEVICE);
//开启设备连接线程
new BluetoothClientConnThread(handler, device).start();
} else if (BluetoothTools.ACTION_STOP_SERVICE.equals(action)) {
//停止后台服务
if (communThread != null) {
communThread.isRun = false;
}
stopSelf();
} else if (BluetoothTools.ACTION_DATA_TO_SERVICE.equals(action)) {
//获取数据
Object data = intent.getSerializableExtra(BluetoothTools.DATA);
if (communThread != null) {
communThread.writeObject(data);
}
}
}
};
//蓝牙搜索广播的接收器
private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//获取广播的Action
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//开始搜索
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//发现远程蓝牙设备
//获取设备
BluetoothDevice bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
discoveredDevices.add(bluetoothDevice);
//发送发现设备广播
Intent deviceListIntent = new Intent(BluetoothTools.ACTION_FOUND_DEVICE);
deviceListIntent.putExtra(BluetoothTools.DEVICE, bluetoothDevice);
sendBroadcast(deviceListIntent);
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//搜索结束
if (discoveredDevices.isEmpty()) {
//若未找到设备,则发动未发现设备广播
Intent foundIntent = new Intent(BluetoothTools.ACTION_NOT_FOUND_SERVER);
sendBroadcast(foundIntent);
}
}
}
};
//接收其他线程消息的Handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//处理消息
switch (msg.what) {
case BluetoothTools.MESSAGE_CONNECT_ERROR:
//连接错误
//发送连接错误广播
Intent errorIntent = new Intent(BluetoothTools.ACTION_CONNECT_ERROR);
sendBroadcast(errorIntent);
break;
case BluetoothTools.MESSAGE_CONNECT_SUCCESS:
//连接成功
//开启通讯线程
communThread = new BluetoothCommunThread(handler, (BluetoothSocket)msg.obj);
communThread.start();
//发送连接成功广播
Intent succIntent = new Intent(BluetoothTools.ACTION_CONNECT_SUCCESS);
sendBroadcast(succIntent);
break;
case BluetoothTools.MESSAGE_READ_OBJECT:
//读取到对象
//发送数据广播(包含数据对象)
Intent dataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_GAME);
dataIntent.putExtra(BluetoothTools.DATA, (Serializable)msg.obj);
sendBroadcast(dataIntent);
break;
}
super.handleMessage(msg);
}
};
/**
* 获取通讯线程
* @return
*/
public BluetoothCommunThread getBluetoothCommunThread() {
return communThread;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
/**
* Service创建时的回调函数
*/
@Override
public void onCreate() {
//discoveryReceiver的IntentFilter
IntentFilter discoveryFilter = new IntentFilter();
discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
discoveryFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);
//controlReceiver的IntentFilter
IntentFilter controlFilter = new IntentFilter();
controlFilter.addAction(BluetoothTools.ACTION_START_DISCOVERY);
controlFilter.addAction(BluetoothTools.ACTION_SELECTED_DEVICE);
controlFilter.addAction(BluetoothTools.ACTION_STOP_SERVICE);
controlFilter.addAction(BluetoothTools.ACTION_DATA_TO_SERVICE);
//注册BroadcastReceiver
registerReceiver(discoveryReceiver, discoveryFilter);
registerReceiver(controlReceiver, controlFilter);
super.onCreate();
}
/**
* Service销毁时的回调函数
*/
@Override
public void onDestroy() {
if (communThread != null) {
communThread.isRun = false;
}
//解除绑定
unregisterReceiver(discoveryReceiver);
super.onDestroy();
}
}
BluetoothServerService
/**
* 蓝牙模块服务器端主控制Service
*/
public class BluetoothServerService extends Service {
//蓝牙适配器
private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//蓝牙通讯线程
private BluetoothCommunThread communThread;
//控制信息广播接收器
private BroadcastReceiver controlReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothTools.ACTION_STOP_SERVICE.equals(action)) {
//停止后台服务
if (communThread != null) {
communThread.isRun = false;
}
stopSelf();
} else if (BluetoothTools.ACTION_DATA_TO_SERVICE.equals(action)) {
//发送数据
Object data = intent.getSerializableExtra(BluetoothTools.DATA);
if (communThread != null) {
communThread.writeObject(data);
}
}
}
};
//接收其他线程消息的Handler
private Handler serviceHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BluetoothTools.MESSAGE_CONNECT_SUCCESS:
//连接成功
//开启通讯线程
communThread = new BluetoothCommunThread(serviceHandler, (BluetoothSocket)msg.obj);
communThread.start();
//发送连接成功消息
Intent connSuccIntent = new Intent(BluetoothTools.ACTION_CONNECT_SUCCESS);
sendBroadcast(connSuccIntent);
break;
case BluetoothTools.MESSAGE_CONNECT_ERROR:
//连接错误
//发送连接错误广播
Intent errorIntent = new Intent(BluetoothTools.ACTION_CONNECT_ERROR);
sendBroadcast(errorIntent);
break;
case BluetoothTools.MESSAGE_READ_OBJECT:
//读取到数据
//发送数据广播(包含数据对象)
Intent dataIntent = new Intent(BluetoothTools.ACTION_DATA_TO_GAME);
dataIntent.putExtra(BluetoothTools.DATA, (Serializable)msg.obj);
sendBroadcast(dataIntent);
break;
}
super.handleMessage(msg);
}
};
/**
* 获取通讯线程
* @return
*/
public BluetoothCommunThread getBluetoothCommunThread() {
return communThread;
}
@Override
public void onCreate() {
//ControlReceiver的IntentFilter
IntentFilter controlFilter = new IntentFilter();
controlFilter.addAction(BluetoothTools.ACTION_START_SERVER);
controlFilter.addAction(BluetoothTools.ACTION_STOP_SERVICE);
controlFilter.addAction(BluetoothTools.ACTION_DATA_TO_SERVICE);
//注册BroadcastReceiver
registerReceiver(controlReceiver, controlFilter);
//开启服务器
bluetoothAdapter.enable(); //打开蓝牙
//开启蓝牙发现功能(300秒)
Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
discoveryIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(discoveryIntent);
//开启后台连接线程
new BluetoothServerConnThread(serviceHandler).start();
super.onCreate();
}
@Override
public void onDestroy() {
if (communThread != null) {
communThread.isRun = false;
}
unregisterReceiver(controlReceiver);
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
BluetoothClientConnThread
/**
* 蓝牙客户端连接线程
*/
public class BluetoothClientConnThread extends Thread{
private Handler serviceHandler; //用于向客户端Service回传消息的handler
private BluetoothDevice serverDevice; //服务器设备
private BluetoothSocket socket; //通信Socket
/**
* 构造函数
* @param handler
* @param serverDevice
*/
public BluetoothClientConnThread(Handler handler, BluetoothDevice serverDevice) {
this.serviceHandler = handler;
this.serverDevice = serverDevice;
}
@Override
public void run() {
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
try {
socket = serverDevice.createRfcommSocketToServiceRecord(BluetoothTools.PRIVATE_UUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
socket.connect();
} catch (Exception ex) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
//发送连接失败消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
return;
}
//发送连接成功消息,消息的obj参数为连接的socket
Message msg = serviceHandler.obtainMessage();
msg.what = BluetoothTools.MESSAGE_CONNECT_SUCCESS;
msg.obj = socket;
msg.sendToTarget();
}
}
BluetoothServerConnThread
/**
* 服务器连接线程
*/
public class BluetoothServerConnThread extends Thread {
private Handler serviceHandler; //用于同Service通信的Handler
private BluetoothAdapter adapter;
private BluetoothSocket socket; //用于通信的Socket
private BluetoothServerSocket serverSocket;
/**
* 构造函数
* @param handler
*/
public BluetoothServerConnThread(Handler handler) {
this.serviceHandler = handler;
adapter = BluetoothAdapter.getDefaultAdapter();
}
@Override
public void run() {
try {
serverSocket = adapter.listenUsingRfcommWithServiceRecord("Server", BluetoothTools.PRIVATE_UUID);
socket = serverSocket.accept();
} catch (Exception e) {
//发送连接失败消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
e.printStackTrace();
return;
} finally {
try {
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (socket != null) {
//发送连接成功消息,消息的obj字段为连接的socket
Message msg = serviceHandler.obtainMessage();
msg.what = BluetoothTools.MESSAGE_CONNECT_SUCCESS;
msg.obj = socket;
msg.sendToTarget();
} else {
//发送连接失败消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
return;
}
}
}
BluetoothCommunThread
/**
* 蓝牙通讯线程
*/
public class BluetoothCommunThread extends Thread {
private Handler serviceHandler; //与Service通信的Handler
private BluetoothSocket socket;
private ObjectInputStream inStream; //对象输入流
private ObjectOutputStream outStream; //对象输出流
public volatile boolean isRun = true; //运行标志位
/**
* 构造函数
*
* @param handler 用于接收消息
* @param socket
*/
public BluetoothCommunThread(Handler handler, BluetoothSocket socket) {
this.serviceHandler = handler;
this.socket = socket;
try {
this.outStream = new ObjectOutputStream(socket.getOutputStream());
this.inStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
} catch (Exception e) {
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
//发送连接失败消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
if (!isRun) {
break;
}
try {
Object obj = inStream.readObject();
//发送成功读取到对象的消息,消息的obj参数为读取到的对象
Message msg = serviceHandler.obtainMessage();
msg.what = BluetoothTools.MESSAGE_READ_OBJECT;
msg.obj = obj;
msg.sendToTarget();
} catch (Exception ex) {
//发送连接失败消息
serviceHandler.obtainMessage(BluetoothTools.MESSAGE_CONNECT_ERROR).sendToTarget();
ex.printStackTrace();
return;
}
}
//关闭流
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outStream != null) {
try {
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 写入一个可序列化的对象
*
* @param obj
*/
public void writeObject(Object obj) {
try {
outStream.flush();
outStream.writeObject(obj);
outStream.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 最后还有一个蓝牙工具类(BluetoothTools)和用于传输的数据类(TransmitBean)代码就不粘了,直接把源码地址发出来