zoukankan      html  css  js  c++  java
  • 蓝牙通信第2篇:建立通信和发送文字消息,文件消息

    一:简介

           当两台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

  • 相关阅读:
    最少说服人数(二分+贪心)
    线段树或树状数组或归并(逆序对)
    线段树(区间更新,区间询问,节点存最小值)
    【Hades】ades是一个开源库,基于JPA和Spring构建,通过减少开发工作量显著的改进了数据访问层的实现
    【hibernate】spring+ jpa + hibername 配置过程遇到的问题
    【方言】Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
    【Bean】 这才是bean,一直没仔细看
    【spring配置】 一组配置文件引出的问题
    org.springframework.web.servlet.view.InternalResourceViewResolver
    org.springframework.orm.jpa.JpaTransactionManager
  • 原文地址:https://www.cnblogs.com/cq-jiang/p/7609747.html
Copyright © 2011-2022 走看看