您的位置:首页 > 其它

安卓蓝牙实现即时通讯功能

2016-05-13 21:28 561 查看

安卓蓝牙实现即时通讯功能

本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)代码就不粘了,直接把源码地址发出来

源码地址:

http://download.csdn.net/detail/benhuo931115/9519599
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: