一:简介
当两台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); } });
2)启动一个线程创建服务端,两个通信的设备需要使用同一个蓝牙标识,如: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