安卓蓝牙实现即时通讯功能
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
相关文章推荐
- twisted 使用
- CSS常用操作——————对齐
- SDUT 3397 小旭追女神-三国乱世
- CodeForces 672B Different is Good
- click.xxx事件触发,参考jquery源码
- Redis 入门
- L3-1. 凑零钱 (DFS)
- 如何在多台机器上共享ios证书
- 在java中使用dom4j解析xml(示例代码)
- UVA12507
- java中的移位运算符
- 异或运算,,,只是一个小数据的枚举
- SDUT 3304 选课大作战
- linux帮助命令及命令补全功能
- invoke*(原有的4中字节码指令)和invokedynamic区别
- 关于 类 Scanner扫描文件的注意事项
- Qt使用镜像源快速安装与更新
- iTextSharp
- 关于树分块算法的一些研究
- 全局修改字体