最近了解了一下蓝牙通信方面的知识,给大家分享一下,希望能给大家带来一些思路,代码写的比较乱,也比较笨拙,大神们就不要喷了。
两个手机通个蓝牙连接会有一个主从关系,就是分客户端和服务端。
首先是客户端代码
//注意这是继承了Thread的哟
public class client extends Thread {
// String address = null;
// 保存远程蓝牙设备的名称
private String name = "";
// 保存搜索到的蓝牙设备的名称
private ArrayList<String> DeviceList = null;
private BluetoothDevice device = null;
private BluetoothSocket socket = null;
// 输入输出流
private InputStream in = null;
private OutputStream out = null;
// 声明接口
OnXiaoXiListener oxl;
BluetoothAdapter adapter = null;
// 写死的UUID
private static final UUID m_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private Context context = null;
// 处理接受到的广播
BluetoothGuangBo guangbo = null;
public client(Context context, BluetoothAdapter adapter) {
// TODO Auto-generated constructor stub
oxl = (OnXiaoXiListener) context;
this.context = context;
this.adapter = adapter;
guangbo = new BluetoothGuangBo();
}
// 定义一个handler,实现异步通信
private Handler hd = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
if (msg.arg1 == 3) {
// 通过接口将接受到的消息返回到Activity
String str = (String) msg.obj;
str = name + ":" + str;
oxl.OnXiaoXi(str);
} else if (msg.arg1 == 1) {
// 提示用户连接成功
Toast.makeText(context, "连接完成", Toast.LENGTH_SHORT).show();
} else if (msg.arg1 == 2) {
// 将搜索到的蓝牙设备名称保存到集合中
String str = msg.obj.toString();
DeviceList.add(str);
}
}
};
// 初始化一些数据
public void init(ArrayList<String> DeviceList) {
BluetoothGuangBo guangbo = new BluetoothGuangBo();
this.DeviceList = DeviceList;
// 动态注册广播“过滤器”
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
// 绑定
context.registerReceiver(guangbo, filter);
}
// 继承BroadcastReceiver类来处理广播
public class BluetoothGuangBo extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// String action = intent.getAction();
// 获取BluetoothDevice对象
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
System.out.println(device.getAddress());
// 保存远程蓝牙设备的名称
name = device.getName();
// 将远程蓝牙设备的MAC地址的通过消息返回到handler的handleMessage(Message msg)方法中
Message msg = new Message();
msg.arg1 = 2;
msg.obj = device.getAddress();
// 将消息放入队列中
hd.sendMessage(msg);
// DeviceList.add(address);
// device = adapter.getRemoteDevice(address);
// Toast.makeText(context, device.getName(), Toast.LENGTH_SHORT)
// .show();
// bluetoothadapter.cancelDiscovery();
// adapter.cancelDiscovery();
}
}
// 选择你要连接的远程蓝牙设备
public void setDevice(int id) {
// getRemoteDevice(String address)--通过MAC地址返回蓝牙设备
device = adapter.getRemoteDevice(DeviceList.get(id));
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
// 通过UUID获取到BluetoothSocket
// 客户端和服务端的蓝牙的UUID必须相同才能通信
socket = device.createRfcommSocketToServiceRecord(m_UUID);
// 数据请求,会阻塞一段时间,所以要放在其他线程中进行
socket.connect();
// 获得输入输出流
in = socket.getInputStream();
out = socket.getOutputStream();
// 创建一个消息对象
Message m = new Message();
// m.arg2=23;
// message提供了两个整型的变量arg1,arg2
// 如果只是传递简单的整形变量,建议使用它们,效率比较高
// m.obj="字符串";
// 当然message也提供了一个Object obj 可以用来传递任何对象
// setData(Bundle data);
// setData()可以传递一个Bundle对象
m.arg1 = 1;
// 赋值完毕之后可以调用handler的方法将消息放到handler的消息队列里面
hd.sendMessage(m);
// 接收消息
jieSou();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("------>失败");
}
}
// 发送消息
public void send(String msg) {
if (socket == null) {
Toast.makeText(context, "没有连接", Toast.LENGTH_SHORT).show();
return;
}
try {
// 向输出流当中写入数据
out.write(msg.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void jieSou() {
try {
while (true) {
byte[] buff = new byte[1024];
//从输入流当中读取数据
int bytes = in.read(buff);
//转换成字符串
String msg = new String(buff, 0, bytes);
// while ((bytes = in.read(buff)) > 0) {
// byte[] buf_data = new byte[bytes];
// for (int i = 0; i < bytes; i++) {
// buf_data[i] = buff[i];
// }
// String msg = new String(buf_data);
// oxl.OnXiaoXi(msg);
// // System.out.println("---数据---:" + s);
// }
// oxl.OnXiaoXi(msg);
//通过message对象将读取到的信息返回出去
Message m = new Message();
m.arg1 = 3;
m.obj = msg;
hd.sendMessage(m);
}
} catch (Exception ex) {
}
}
//在UI线程中实现此接口对信息的处理
public interface OnXiaoXiListener {
public void OnXiaoXi(String msg);
}
}
然后是服务端代码
public class serverDuan extends Thread {
// 保存远程设备蓝牙的名称
private String name = "";
private BluetoothAdapter adapter = null;
BluetoothServerSocket serverSocket = null;
BluetoothSocket socket = null;
private Context context = null;
InputStream in = null;
OutputStream out = null;
// 声明一个接口
OnXiaoXi2Listener oxl;
// 和客户端一样的UUID
private static final UUID m_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
public serverDuan(Context context, BluetoothAdapter adapter) {
// TODO Auto-generated constructor stub
oxl = (OnXiaoXi2Listener) context;
this.adapter = adapter;
this.context = context;
}
private Handler hd = new Handler() {
public void handleMessage(Message msg) {
if (msg.arg1 == 2) {
//同样,通过接口将信息返回出去
String str = (String) msg.obj;
str = name + ":" + str;
oxl.OnXiaoXi2(str);
} else if (msg.arg1 == 1) {
//提示连接成功
Toast.makeText(context, "连接完成", Toast.LENGTH_SHORT).show();
}
};
};
@Override
public void run() {
// TODO Auto-generated method stub
try {
//获取BluetoothServerSocket
serverSocket = adapter.listenUsingRfcommWithServiceRecord(
"Assassin",//服务名称,可以是任意的字符串
m_UUID);
//accept()--等待建立连接
//阻塞式方法,要异步进行
//服务端发出了建立连接的请求,客户端才能与之连接
//返回客户端的BluetoothSocket,从而获取输入输出流
//因为服务端是没有自己的输入输出流的
socket = serverSocket.accept();
//获取到已连接的蓝牙设备
BluetoothDevice d = socket.getRemoteDevice();
//获取其蓝牙设备名称
name = d.getName();
//获取输入输出流
in = socket.getInputStream();
out = socket.getOutputStream();
//通过message对象返回消息提示连接成功
Message m = new Message();
m.arg1 = 1;
hd.sendMessage(m);
// 接受消息
jieSou();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("------>失败");
}
}
// 发送消息
public void send(String msg) {
if (socket == null) {
Toast.makeText(context, "没有连接", Toast.LENGTH_SHORT).show();
return;
}
try {
out.write(msg.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//接受消息
private void jieSou() {
try {
// byte[] buff = new byte[1024];
while (true) {
System.out.println("--1--");
byte[] buff = new byte[1024];
int bytes = in.read(buff);
String msg = new String(buff, 0, bytes);
// while ((bytes = in.read(buff)) > 0) {
// byte[] buf_data = new byte[bytes];
// for (int i = 0; i < bytes; i++) {
// buf_data[i] = buff[i];
// }
// String msg = new String(buf_data);
// oxl.OnXiaoXi2(msg);
// // System.out.println("---数据---:" + s);
// }
// oxl.OnXiaoXi2(msg);
Message m = new Message();
m.arg1 = 2;
m.obj = msg;
hd.sendMessage(m);
}
} catch (Exception ex) {
}
}
public interface OnXiaoXi2Listener {
public void OnXiaoXi2(String msg);
}
}
看完大家可能发现有很多重复代码,过程就是这样,大家可以自己去设计,优化。
Activity中的代码这里就不多说了,自己随意设计了