Android BLE与终端通信(四)——实现服务器与客户端即时通讯功能
来源:互联网 发布:网络神学院网站 编辑:程序博客网 时间:2024/06/07 19:38
Android BLE与终端通信(四)——实现服务器与客户端即时通讯功能
前面几篇一直在讲一些基础,其实说实话,蓝牙主要为多的还是一些概念性的东西,当你把概念都熟悉了之后,你会很简单的就可以实现一些逻辑,主要是Socket和I/O流的操作,今天就来一起做一个聊天的小程序,我们都知道,我们实现蓝牙连接,蓝牙是有主从关系的,所以有客户端和服务端之分,我们新建一个工程——BLE_QQ(hh,毕竟是即时通讯嘛,和QQ挨个边)
参考Google的API:http://developer.android.com/guide/topics/connectivity/bluetooth.html
在开始之前,别忘了添加权限
<uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
一.OpenBluetooth
Google的API上说的是十分的清楚,我们作为初学者要把他当做说明书一样来看待
这样的话,我们就来实现打开蓝牙并且打开可见性,可见性默认是120s,MAX为3600s,这里在强调一遍,打开蓝牙有两种方式,一种是弹框提示,一种是强制打开,这在之前也是提过好多次了的
/** * 打开蓝牙并且搜索 */ public void openBluetooth(View v) { // 开启搜索 Intent discoverableIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); // 设置可见性300s discoverableIntent.putExtra( BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); // 强制打开 // mBluetoothAdapter.enable(); }
CloseBluetooth
关闭蓝牙也就直接调用BluetoothAdapter的disable()方法;
/** * 关闭蓝牙 */ public void closeBluetooth(View v) { mBluetoothAdapter.disable(); }
客户端
我们在MainActivity中写一个button直接跳转到ClientActivity中去
/** * 打开客户端 */ public void Client(View v) { startActivity(new Intent(this, ClientActivity.class)); }
ClientActivity
package com.example.ble_qq;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.SocketOptions;import java.util.UUID;import com.example.ble_qq.ServiceActivity.ReceiverInfoThread;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothDevice;import android.bluetooth.BluetoothServerSocket;import android.bluetooth.BluetoothSocket;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.text.TextUtils;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;/** * 客户端 * * @author LGL * */public class ClientActivity extends Activity { // 连接成功 private static final int CONN_SUCCESS = 0x1; // 连接失败 private static final int CONN_FAIL = 0x2; private static final int RECEIVER_INFO = 0x3; // 设置文本框为空 private static final int SET_EDITTEXT_NULL = 0x4; // 接收到的消息 private TextView tv_content; // 输入框 private EditText et_info; // 发送按钮 private Button btn_send; // 本地蓝牙适配器 private BluetoothAdapter mBluetoothAdapter = null; // 远程设备 private BluetoothDevice device = null; // 蓝牙设备Socket客户端 private BluetoothSocket socket = null; private boolean isReceiver = true; // 设备名称 private static final String NAME = "LGL"; // 输入输出流 private PrintStream out; private BufferedReader in; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setTitle("客户端"); setContentView(R.layout.activity_client); initView(); // 初始化Socket客户端连接 init(); } private void initView() { // 初始化 tv_content = (TextView) findViewById(R.id.tv_content); et_info = (EditText) findViewById(R.id.et_info); btn_send = (Button) findViewById(R.id.btn_send); } private void init() { tv_content.setText("客户端已经启动,正在与服务端连接...\n"); // 开始连接 new Thread(new Runnable() { @Override public void run() { try { // 得到本地蓝牙适配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 通过本地适配器得到地址,这个地址可以公共扫描来获取,就是getAddress()返回的地址 device = mBluetoothAdapter .getRemoteDevice("98:6C:F5:CE:0E:81"); // 根据UUID返回一个socket,要与服务器的UUID一致 socket = device.createRfcommSocketToServiceRecord(UUID .fromString("00000000-2527-eef3-ffff-ffffe3160865")); if (socket != null) { // 连接 socket.connect(); // 处理流 out = new PrintStream(socket.getOutputStream()); in = new BufferedReader(new InputStreamReader(socket .getInputStream())); } // 连接成功发送handler handler.sendEmptyMessage(CONN_SUCCESS); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Message mes = handler.obtainMessage(CONN_FAIL, e.getLocalizedMessage()); handler.sendMessage(mes); } } }).start(); } /** * Handler接收消息 * */ private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case CONN_SUCCESS: setInfo("连接成功! \n"); btn_send.setEnabled(true); Log.i("设备的名称", device.getName()); Log.i("设备的UUID", device.getUuids() + ""); Log.i("设备的地址", device.getAddress()); // 开始接收信息 new Thread(new ReceiverInfoThread()).start(); break; case CONN_FAIL: setInfo("连接失败! \n"); setInfo(msg.obj.toString() + "\n"); break; case RECEIVER_INFO: setInfo(msg.obj.toString() + "\n"); break; case SET_EDITTEXT_NULL: et_info.setText(""); break; } } }; /** * 接收消息的线程 */ class ReceiverInfoThread implements Runnable { @Override public void run() { String info = null; while (isReceiver) { try { info = in.readLine(); Message msg = handler.obtainMessage(RECEIVER_INFO); handler.sendMessage(msg); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 发送消息 */ public void SendText(View v) { final String text = et_info.getText().toString(); // 不能为空 if (!TextUtils.isEmpty(text)) { Toast.makeText(this, "不能为空", Toast.LENGTH_SHORT).show(); } new Thread(new Runnable() { @Override public void run() { // 输出 out.println(text); out.flush(); // 把文本框设置为空 handler.sendEmptyMessage(SET_EDITTEXT_NULL); } }).start(); } /** * 拼接文本信息 */ private void setInfo(String info) { StringBuffer sb = new StringBuffer(); sb.append(tv_content.getText()); sb.append(info); tv_content.setText(sb); }}
服务端
我们在MainActivity中写一个button直接跳转到ServiceActivity中去
/** * 打开服务端 */ public void Service(View v) { startActivity(new Intent(this, ServiceActivity.class)); }
ServiceActivity
package com.example.ble_qq;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.util.UUID;import android.app.Activity;import android.bluetooth.BluetoothAdapter;import android.bluetooth.BluetoothServerSocket;import android.bluetooth.BluetoothSocket;import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.os.Message;import android.text.TextUtils;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;/** * 服务端 * * @author LGL * */public class ServiceActivity extends Activity { // 连接成功 private static final int CONN_SUCCESS = 0x1; // 连接失败 private static final int CONN_FAIL = 0x2; private static final int RECEIVER_INFO = 0x3; // 设置文本框为空 private static final int SET_EDITTEXT_NULL = 0x4; // 接收到的消息 private TextView tv_content; // 输入框 private EditText et_info; // 发送按钮 private Button btn_send; // 本地蓝牙适配器 private BluetoothAdapter mBluetoothAdapter = null; // 蓝牙设备Socket服务端 private BluetoothServerSocket serviceSocket = null; // 蓝牙设备Socket客户端 private BluetoothSocket socket = null; // 设备名称‘ private static final String NAME = "LGL"; private boolean isReceiver = true; // 输入输出流 private PrintStream out; private BufferedReader in; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setTitle("服务端"); setContentView(R.layout.activity_service); initView(); // 创建蓝牙服务端的Socket initService(); } private void initView() { // 初始化 tv_content = (TextView) findViewById(R.id.tv_content); et_info = (EditText) findViewById(R.id.et_info); btn_send = (Button) findViewById(R.id.btn_send); } private void initService() { tv_content.setText("服务器已经启动,正在等待设备连接...\n"); // 开启线程操作 new Thread(new Runnable() { @Override public void run() { // 得到本地适配器 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // 创建蓝牙Socket服务端 try { // 服务端地址 serviceSocket = mBluetoothAdapter .listenUsingInsecureRfcommWithServiceRecord( NAME, UUID.fromString("00000000-2527-eef3-ffff-ffffe3160865")); // 阻塞线程等待连接 socket = serviceSocket.accept(); if (socket != null) { // I/O流 out = new PrintStream(socket.getOutputStream()); in = new BufferedReader(new InputStreamReader(socket .getInputStream())); } // 连接成功发送handler handler.sendEmptyMessage(CONN_SUCCESS); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); Message mes = handler.obtainMessage(CONN_FAIL, e.getLocalizedMessage()); handler.sendMessage(mes); } } }).start(); } /** * Handler接收消息 * */ private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case CONN_SUCCESS: setInfo("连接成功! \n"); btn_send.setEnabled(true); new Thread(new ReceiverInfoThread()).start(); break; case CONN_FAIL: setInfo("连接失败! \n"); setInfo(msg.obj.toString() + "\n"); break; case RECEIVER_INFO: setInfo(msg.obj.toString() + "\n"); break; case SET_EDITTEXT_NULL: et_info.setText(""); break; } } }; /** * 接收消息的线程 */ class ReceiverInfoThread implements Runnable { @Override public void run() { String info = null; while (isReceiver) { try { info = in.readLine(); Message msg = handler.obtainMessage(RECEIVER_INFO); handler.sendMessage(msg); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } /** * 发送消息 */ public void SendText(View v) { final String text = et_info.getText().toString(); // 不能为空 if (!TextUtils.isEmpty(text)) { Toast.makeText(this, "不能为空", Toast.LENGTH_SHORT).show(); } new Thread(new Runnable() { @Override public void run() { // 输出 out.println(text); out.flush(); // 把文本框设置为空 handler.sendEmptyMessage(SET_EDITTEXT_NULL); } }).start(); } /** * 拼接文本信息 */ private void setInfo(String info) { StringBuffer sb = new StringBuffer(); sb.append(tv_content.getText()); sb.append(info); tv_content.setText(sb); }}
XML
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <EditText android:id="@+id/et_info" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_send" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="SendText" android:text="发送" /></LinearLayout>
实际上运行结果是这样的,我们必须准备两部手机,然后先用蓝牙配对,在进行连接
这样我们两个设备就配对成功了
Demo下载地址:http://download.csdn.net/detail/qq_26787115/9420355
2 0
- Android BLE与终端通信(四)——实现服务器与客户端即时通讯功能
- Android BLE与终端通信(四)——实现服务器与客户端即时通讯功能
- Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信
- Android BLE与终端通信(三)——客户端与服务端通信过程以及实现数据通信
- Android BLE开发——Android手机与BLE终端通信初识
- Android BLE开发——Android手机与BLE终端通信初识
- Android BLE蓝牙4.0开发—Android手机与BLE终端通信
- Android手机与BLE终端通信
- Android BLE开发之Android手机与BLE终端通信
- Android BLE开发之Android手机与BLE终端通信
- Android BLE开发之Android手机与BLE终端通信
- Android BLE开发之Android手机与BLE终端通信
- Android BLE开发之Android手机与BLE终端通信
- Android BLE开发之Android手机与BLE终端通信
- Android BLE与终端通信(二)——Android Bluetooth基础科普以及搜索蓝牙设备显示列表
- Android BLE与终端通信(二)——Android Bluetooth基础搜索蓝牙设备显示列表
- Android提高之Android手机与BLE终端通信
- 手把手教你Android手机与BLE终端通信--搜索
- HDU 3802 Ipad,IPhone
- 20160126.CCPP体系详解(0005天)
- 深入浅出RPC——浅出篇
- Tomcat搭建solr伪集群(solr5.2.1+tomcat8.0.23+zookeeper3.4.6)
- 关于NSInteger 类型 如何打印不出警告的解决方案
- Android BLE与终端通信(四)——实现服务器与客户端即时通讯功能
- svn——'svn'不是内部或外部命令,也不是可运行的程序或批处理文件
- Swift 类,结构体,枚举使用总结
- PCH Warning: header stop cannot be in a macro or #if block.
- 蓝桥杯 - 区间k大数查询
- 【js】关于checkbox
- VC API常用函数简单例子大全
- 2016.1.27win装系统备忘
- android webView.loadData乱码问题的解决