蓝牙SPP接收到的一些包帧会丢失还是?

2023-12-08

我使用android示例代码进行修改。只想收到包裹 但是,我的代码只在这里修改

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
            switch (msg.arg1) {
            case BluetoothChatService.STATE_CONNECTED:
                mTitle.setText(R.string.title_connected_to);
                mTitle.append(mConnectedDeviceName);
                mConversationArrayAdapter.clear();
                break;
            case BluetoothChatService.STATE_CONNECTING:
                mTitle.setText(R.string.title_connecting);
                break;
            case BluetoothChatService.STATE_LISTEN:
            case BluetoothChatService.STATE_NONE:
                mTitle.setText(R.string.title_not_connected);
                break;
            }
            break;
        case MESSAGE_WRITE:
            byte[] writeBuf = (byte[]) msg.obj;
            // construct a string from the buffer
            String writeMessage = new String(writeBuf);
            mConversationArrayAdapter.add(writeMessage);
            break;
        case MESSAGE_READ:

            byte[] readBuf = (byte[]) msg.obj;
            // construct a string from the valid bytes in the buffer
            //String readMessage = new String(readBuf, 0, msg.arg1);
            //String readMessage = BytesTrans_fill.bytesToHexString(readBuf);
            Log.d("read", BytesTrans.bytes2HexString(readBuf,msg.arg1));
            String readMessage = BytesTrans.bytes2HexString(readBuf,msg.arg1);
            ppV.setText(ppV.getText().toString() + readMessage + "★");
            break;
        case MESSAGE_DEVICE_NAME:
            // save the connected device's name
            mConnectedDeviceName = msg.getData().getString(
                    DEVICE_NAME);
            Toast.makeText(getApplicationContext(), "Connected to "
                           + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
            break;
        case MESSAGE_TOAST:
            Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
                           Toast.LENGTH_SHORT).show();
            break;
        }
    }
};

和蓝牙聊天服务

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");

        byte[] buffer = new byte[1024];

        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                break;
            }
        }
    }

并添加这个功能

package com.example.android.BluetoothChat;

public class BytesTrans {
    public static String byte2HexString(byte b) {
        String ret = "";
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase()  + " ";
        return ret;
    }

    public static String bytes2HexString(byte[] b, int count) {
        String ret = "";
        for (int i = 0; i < count; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase() + " ";
        }
        return ret;
    }
    /*public static String String2byte(String b)
    {
        String[] ttt;
        for (int i = 0; i < b.length(); i++)
        {
            for (int j= i; j<=i+1; j++)
            {
                ttt[i] = b;
            }

        }           

        String ttmp = "";
        String tmp = "";





        ret += tmp;
    }*/
    public static int hexToTen(String b) {
        int D2 = Integer.parseInt(b,16);


        return D2;
        }
    }

但这个程序有时甚至不显示我的发送包的框架

我发送这样的包裹:

aa07210820001202140934390000000000000000000000000000000000000000000297c0fe6b

但有时会收到包裹:

aa000297c0fe6b02131452470000000000000000000000000000000000000000000297c0fe6b

我如何更改我的代码以接收完整包的框架


您还没有显示任何蓝牙接口代码。然而,如果这在很大程度上基于 BluetoothChat 示例,那么就目前的 BluetoothChat 示例而言,存在一个简单的问题:基本上,当read()由蓝牙套接字创建并放入字节数组中,该数组引用使用Handler,就像你正在做的那样。实际的问题是,如果使用 BluetoothChat 示例以比打字速度更快的速度接收数据,那么您会开始看到字符丢失或变得混乱,因为后续的操作会导致字符丢失或变得混乱。read()正在覆盖数组,而 UI 仍在读取数组以提取收到的最后一堆字符。

所以,如果你的MESSAGE_WRITE对象包含对您正在创建套接字的数组的引用read()调用,那么这可能就是您丢失字符的原因。因此,请尝试发送copy的数组,使用Arrays.copyOf(), 在里面Message。或者,也许您可​​以使用循环缓冲区布置。

当我使用 BluetoothChat 示例作为我的项目的基础时,我正是遇到了这个问题。我个人为解决这个问题(并消除复制缓冲区等的需要)所做的是实现一种机制,通过该机制我可以告诉蓝牙连接线程(包含阻塞套接字的线程).read()),通过方法调用,我期望响应有多少字节(幸运的是,我正在处理的协议允许知道响应长度)。然后连接线程只发送一个Message当收到完整的响应时,而不是发送几个Message包含对 UI 的响应片段。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

蓝牙SPP接收到的一些包帧会丢失还是? 的相关文章

随机推荐

  • If Let 错误 - 条件绑定的初始化程序必须具有可选类型,而不是“[NSObject : AnyObject]”

    这是我的代码 PFUser logInWithUsernameInBackground email password password user PFUser error NSError gt Void in if user nil Pus
  • std::map 放置 gcc 4.8.2

    我正在尝试使用 std map 的 emplace 函数 但它似乎没有实现 但我读到它是在 4 8 中实现的 以下代码 std map
  • 其他库中类型之间的 C++ 转换运算符

    为了方便起见 我希望能够在其他库中定义的两种类型之间进行转换 具体来说 QString来自 Qt 库和UnicodeString来自 ICU 库 现在 我已经在项目命名空间中创建了实用函数 namespace MyProject const
  • 堆栈面板的水平滚动不起作用

    我尝试创建一个可滚动的水平 StackPanel 但我没有成功 目前我的 StackPanel 带有auto宽度 问题可能就在这里 包含一些项目 例如grids 现在 如果我的所有网格在 StackPanel 中都不可见 宽度太短 我将无法
  • 计算输入中的行数、单词数和字符数

    现在我正在阅读一本关于 C 的书 并且在书中遇到了一个我无法开始工作的示例 include
  • Shell 脚本中的十六进制到十进制

    有人可以帮我在 shell 脚本中将十六进制数转换为十进制数吗 例如 我想转换十六进制数bfca3000使用 shell 脚本转换为十进制 我基本上想要两个十六进制数的差 我的代码是 var3 echo ibase 16 var1 bc v
  • 带有额外字段的 Django Rest Framework 用户注册

    我正在尝试使用 DRF 来允许用户通过我的 API 创建新的用户帐户 我有一些可能与正常情况不同的要求 成功创建后 需要使用 DRF 的令牌功能返回用户令牌 所有 POST 字段都需要验证 我希望能够发布将存储在配置文件模型中的用户电话号码
  • 如何用文本文件项填充组合框!

    我有一个文本文件 其中包含以下类型的项目 wett45456 4556 45657 898 tyu5878 4566 7989 55565 现在我有一个 Windows 窗体 该窗体上有一个组合框 现在我想用每行的第一项填充组合框wett4
  • @font-face 和 Header 设置 Access-Control-Allow-Origin "*"

    我使用了以下规则来允许我们的静态域托管字体 但是当启用浏览器缓存时 我遇到了浏览器 firefox safari 不使用字体的问题
  • devise - 无法在 Rails 视图中显示登录或注销

    我现在正在使用 devise 进行基本身份验证 当我去localhost 3000 users sign in我将能够登录 或者如果我登录后前往那里 我将收到相应的消息 您已经登录 然而 user signed in 始终评估为 false
  • Spring xml ioc 相对于 Java 实例化有什么好处? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 好吧 这个问题会得到很多反
  • 将 Pandoc 与 Swift 结合使用

    我正在尝试使用 Pandoc 将 LaTeX 转换为 Markdown 我需要创建一个文件 然后运行 pandoc 终端命令 问题是我创建的文件不在我运行终端命令的同一目录中 我尝试使用 shell cd 但它不会将您移动到用户的文件夹 有
  • Swift - 将协议数组向上转换为超级协议数组会导致错误

    在 Swift 中 我注意到我可以向上转换一个符合名为的协议的对象 比方说SubProtocol到另一个称为SuperProtocol这是一个超级协议SubProtocol 但我不能对协议数组做同样的事情 这是我在 Playground 中
  • 使用 pywin32 Dispatch 在 Excel 中的命名工作表之后移动工作表

    我有大量文件 需要将其中的某个工作表复制到另一个工作簿 需要将它们放置在具有特定名称的工作表之后 同时保留要移动的工作表中的所有格式 我在另一个线程中看到 pywin32 将是可行的方法 但是我很难在指定的工作表 之后 复制此工作表 xl
  • 设计一个指令序列,以便在使用偏移量解码时执行其他操作

    这个问题是后续问题那个问题 要设置此问题的上下文 请考虑无空编程 这是一种将指令序列 shellcode 伪装成字符串的技术 在C编程语言中 字节0标志着字符串的结束 因此指令序列必须设计为不包含任何此类字节 否则它将被滥用的字符串操作函数
  • 文本框出现在单选按钮检查上

    我有以下 table td align center td table
  • pandas - groupby 和重新缩放值

    我想向此数据框添加一个重新缩放的列 I Value A 1 A 4 A 2 A 5 B 1 B 2 B 1 这样新列 我们称之为scale 遵循一个函数value每组的列I 该函数只是每个组范围的标准化 lambda x x min x m
  • 如何在单个 MSI 中部署多个项目?

    我的解决方案中有 3 个要部署的项目 是否有一种快速有效的方法可以使用 Visual Studio 的安装项目来使用一个 MSI 部署所有三个应用程序 并让用户在安装过程中决定要安装哪些应用程序 我有 3 个单独应用程序的设置项目 我还有一
  • Google 表格中的一项功能可处理多个工作表

    在 Google Sheets 中我必须重复一个函数 因为getSheetByName 不接受一系列工作表 它只接受一张工作表 有没有一种方法可以让一个函数循环指定的工作表 不是所有工作表 i e 表 1 表 2 等 function re
  • 蓝牙SPP接收到的一些包帧会丢失还是?

    我使用android示例代码进行修改 只想收到包裹 但是 我的代码只在这里修改 private final Handler mHandler new Handler Override public void handleMessage Me