一:简介
当两台android设备正常连接后,搜索与连接文章在这里(蓝牙搜索与连接),各自需要开启一个服务端和客户端接收消息(类似于socket),两台设备需要邦定同一个通信标识,通常是一个uuid。如:00001101-0000-1000-8000-00805F9B34FB
二:创建蓝牙服务端
1)在已配对的蓝牙列表,选择需要通信的蓝牙设备
bondDevicesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mBluetoothAdapter.cancelDiscovery();
ClsUtils.closeDiscoverableTimeout(mBluetoothAdapter);
final BluetoothDevice bluetoothDevice = bondDevices.get(position);//用户选择的蓝牙设备
Bundle bun = new Bundle();
Constant.setBluetoothDevice(bluetoothDevice);
Intent intent = new Intent(mContenxt, ClientSendMsgAct.class);
intent.putExtras(bun);
startActivity(intent);
}
});
Constant.PRIVATE_UUID
@Override
public void run() {
try {
adapter = BluetoothAdapter.getDefaultAdapter();
serverSocket = adapter.listenUsingInsecureRfcommWithServiceRecord("myBluetooth", Constant.PRIVATE_UUID);
mHandler.obtainMessage(CREATE_SUCCESS).sendToTarget();
while (status) {
socket = serverSocket.accept();
doWork();
}
} catch (Exception e) {
e.printStackTrace();
setActivityMsg(CREATE_FAIL, "创建服务线程出现异常:" + e.getMessage());
}
}
三:发送文本消息
1)发送文字消息前,需要创建一个线程,使用DataOutputStream来发送消息
BluetoothDevice serverDevice;//用户选择的蓝牙设备,详见2.1(在已配对的蓝牙列表,选择需要通信的蓝牙设备)代码
BluetoothSocket socket = serverDevice.createInsecureRfcommSocketToServiceRecord(Constant.PRIVATE_UUID);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
String sendMessage = "nihao";
int f_len = sendMessage.getBytes("UTF-8").length; //消息长度
long totalLen = 4 + 1 + 1 + f_len;//数据的总长度
byte[] data = new byte[f_len];
data = sendMessage.getBytes("UTF-8");
dataOutputStream.writeLong(totalLen); //1.写入数据的总长度
dataOutputStream.writeByte(type);//2.写入类型
dataOutputStream.writeByte(f_len); //3.写入消息的长度
dataOutputStream.write(data); //4.写入消息数据
dataOutputStream.flush();
目前是测试,每发送一条消息启动一个线程,消息发送也不频繁,所以不会有影响
BluetoothClientThread bluetoothClientThread = new BluetoothClientThread(clientHandler,mContext,msg,socket);
new Thread(bluetoothClientThread).start();
2)接收文字消息是在最早我们创建的,服务端线程里面
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
long totalLen = dataInputStream.readLong();//总长度
byte type = dataInputStream.readByte();//类型
byte len = dataInputStream.readByte();//消息长度
byte[] ml = new byte[len];
int size = 0;
int receivelen = 0;
while (receivelen < len) {
size = dataInputStream.read(ml, 0, ml.length);
receivelen += size;
}
msg = new String(ml, "UTF-8");
setActivityMsg(MSG, msg);//将消息回调到activity,并且刷新接收到的消息
3)发送图片消息
发送图片消息需要分为两步发送,第一次发图片名称,大小等,第二次才发正式发送图片,和soket一样。
a)发送图片名称,大小
fins=new FileInputStream(Constant.FILE_PATH+imagePath);
long fileDataLen = fins.available(); //文件的总长度
int f_len=imagePath.getBytes("UTF-8").length; //文件名长度
byte[] data=new byte[f_len];
data=imagePath.getBytes("UTF-8");
long totalLen = 4+1+1+f_len+fileDataLen;//数据的总长度
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeLong(totalLen); //1.写入数据的总长度
dataOutputStream.writeByte(type);//2.写入类型
dataOutputStream.writeByte(f_len); //3.写入文件名的长度
dataOutputStream.write(data); //4.写入文件名的数据
dataOutputStream.flush();
b)正式发送图片
FileInputStream fins=new FileInputStream("实际图片路径");
while((size=fins.read(buffer, 0, 1024*10))!=-1)
{
dataOutputStream.write(buffer, 0, size);
dataOutputStream.flush();
sendlen+=size;
i++;
if(i%10==0){
long time2=Calendar.getInstance().getTimeInMillis();
tspeed=sendlen/(time2-time1)*1000/1024;
}
downbl = ((sendlen * 100) / fileDataLen);
Message msg = mHandler.obtainMessage(SEND_PROGRESS);
Bundle bun = new Bundle();
bun.putFloat("tspeed",downbl);
msg.setData(bun);
mHandler.sendMessage(msg);//更新发送进度
}
4)接收图片消息
接收和发送一样,需要分为两步,第一步,接收图片名称,第二步,接收图片流
a)接收图片名称
byte len = dataInputStream.readByte();//文件名长度
byte[] fn = new byte[len];
dataInputStream.read(fn);//读取文件名
String filename = new String(fn, "UTF-8");
b)接收图片流
byte[] buffer = new byte[1024 * 1024];
long datalength = totalLen - 1 - 4 - 1 - fn.length;//文件数据
long receivelen = 0;
while (receivelen < datalength) {
size = dataInputStream.read(buffer);
fileOutputStream.write(buffer, 0, size);
receivelen += size;
i++;
if (i % 10 == 0) {
long time2 = Calendar.getInstance().getTimeInMillis();
tspeed = receivelen / (time2 - time1) * 1000 / 1024;
}
downbl = (receivelen * 100) / datalength;
}
接收文字消息,文本消息代码结束了。
demo代码下载:github