草庐IT

Android 滞后/不稳定的蓝牙连接

codeneng 2023-03-28 原文

Android lagging / instable bluetooth connection

我在使用不安全的 RFCOMM 连接连接到 WML-C46 AH 蓝牙芯片时遇到问题。我编写了一个只有相关代码的 android 应用程序来向您展示我的问题。

应用程序

该应用程序只有一个按钮。如果单击此按钮,则会启动蓝牙设备发现。发现完成后,应用程序连接到蓝牙设备(我只使用一个蓝牙设备进行测试,因此找不到任何其他设备)。然后它打开一个输入流来读取这个设备的数据。如果连接中断(抛出 ioexception)或再次单击按钮,则关闭连接(关闭所有线程、套接字和流)。如果您再次单击该按钮,则会启动新设备发现,依此类推...

问题

连接不正常。数据输入流似乎有点滞后,有时连接中断而没有任何明显的原因(IOException:软件导致连接中止或 IOException:再试一次)。它几乎是 android 蓝牙聊天示例的简化版本,它使用设备发现而不是配对设备和一个活动。

密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
public class MainActivity extends Activity implements View.OnClickListener {

    BluetoothDevice btDevice;
    BluetoothSocket btSocket;
    InputStream inStream;
    OutputStream outStream;
    Object lock = new Object();
    boolean connected = false;
    boolean canceled = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button) findViewById(R.id.button1);
        btn.setOnClickListener(this);

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        getApplicationContext().registerReceiver(btReceiver, filter);
        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        getApplicationContext().registerReceiver(btReceiver, filter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onClick(View arg0) {
        if (!connected) {
            connected = true;
            canceled = false;

            new Thread(new Runnable() {
                @Override
                public void run() {
                    BluetoothAdapter btAdapter = BluetoothAdapter
                            .getDefaultAdapter();

                    try {
                        if (btAdapter.isDiscovering())
                            btAdapter.cancelDiscovery();
                        btAdapter.startDiscovery();

                        // block until device discovery has finished
                        synchronized (lock) {
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                Log.d("EXCEPTION","", e);
                            }
                        }

                        btSocket = btDevice.createInsecureRfcommSocketToServiceRecord(UUID
                                .fromString("00001101-0000-1000-8000-00805F9B34FB"));
                        btSocket.connect();

                        inStream = btSocket.getInputStream();
                        outStream = btSocket.getOutputStream();

                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                while (!canceled) {
                                    try {
                                        int in;
                                        while ((in = inStream.read()) != -1) {
                                            Log.d("Received new byte:", in
                                                    +"");
                                        }
                                    } catch (IOException e) {
                                        Log.d("EXCEPTION IN LISTENER","", e);
                                        disconnect();
                                    }
                                }
                            }
                        }).start();
                    } catch (IOException e) {
                        Log.d("","", e);
                    }
                }
            }).start();
        } else {
            disconnect();
        }
    }

    private void disconnect() {
        connected = false;
        canceled = true;

        try {
            btSocket.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING","", e);
        }
        try {
            inStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING","", e);
        }
        try {
            outStream.close();
        } catch (Exception e) {
            Log.d("EXCEPTION DISCONNECTING","", e);
        }

        btDevice = null;
        btSocket = null;
        inStream = null;
        outStream = null;
    }

    private final BroadcastReceiver btReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            try {
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    synchronized (lock) {
                        lock.notifyAll();
                    }
                }
            } catch (Exception e) {
                Log.d(this.getClass().getName(),"", e);
            }
        }
    };
}

我只是使用阻塞方法或自己进行阻塞。因此,连接建立工作非常程序化。当我调整它时,我可能已经丢失了 android 示例的连接流程,但我找不到问题。

输出

建立连接:

1
2
3
4
5
6
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketNative
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): ...fd 47 created (RFCOMM, lm = 0)
01-16 16:52:46.234: V/BluetoothSocket.cpp(6961): initSocketFromFdNative
01-16 16:52:46.257: D/BluetoothUtils(6961): isSocketAllowedBySecurityPolicy start : device null
01-16 16:52:47.171: V/BluetoothSocket.cpp(6961): connectNative
01-16 16:52:47.570: V/BluetoothSocket.cpp(6961): ...connect(47, RFCOMM) = 0 (errno 115)

连接中断:

1
2
3
4
5
6
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961): java.io.IOException: Software caused connection abort
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.readNative(Native Method)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:388)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:60)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at com.example.bttest.MainActivity$2$1.run(MainActivity.java:100)
01-16 16:53:38.539: D/EXCEPTION IN LISTENER(6961):  at java.lang.Thread.run(Thread.java:856)

谢谢!


发现问题。蓝牙设备未按预期工作,并在几秒钟后关闭连接。然而,代码工作得很好。

  • 你设备的安卓版本是多少??你找到解决办法了吗??
  • 导致问题的是实际的蓝牙设备,而不是 android 或 BluetoothDevice 类;)

有关Android 滞后/不稳定的蓝牙连接的更多相关文章

  1. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  2. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  5. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  6. ruby - Faye WebSocket,关闭处理程序被触发后重新连接到套接字 - 2

    我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d

  7. ruby-on-rails - 什么会导致与 APNS 的连接间歇性断开连接? - 2

    我有一个ruby​​脚本可以打开与Apple推送服务器的连接并发送所有待处理的通知。我看不出任何原因,但当Apple断开我的脚本时,我遇到了管道损坏错误。我已经编写了我的脚本来适应这种情况,但我宁愿只是找出它发生的原因,这样我就可以在第一时间避免它。它不会始终根据特定通知断开连接。它不会以特定的字节传输大小断开连接。一切似乎都是零星的。您可以在单个连接上发送的数据传输或有效负载计数是否有某些限制?看到人们的解决方案始终保持一个连接打开,我认为这不是问题所在。我看到连接在3次通知后断开,我看到它在14次通知后断开。我从未见过它能超过14点。有没有人遇到过这种类型的问题?如何处理?

  8. ruby - 如何断开现有的 ruby​​ 续集与数据库的连接? - 2

    我的意思是之前建立的那个DB=Sequel.sqlite('my_blog.db')或DB=Sequel.connect('postgres://user:password@localhost/my_db')或DB=Sequel.postgres('my_db',:user=>'user',:password=>'password',:host=>'localhost')等等。Sequel::Database类没有名为“disconnect”的公共(public)实例方法,尽管它有一个“connect”。也许有人已经遇到过这个问题。我将不胜感激。 最佳答案

  9. ruby-on-rails - 遗留数据库的 ActiveRecord 连接表 - 2

    我有一个遗留数据库,我正在努力让ActiveRecord使用它。我遇到了连接表的问题。我有以下内容:classTvShow然后我有一个名为tvshowlinkepisode的表,它有2个字段:idShow、idEpisode所以我有2个表和它们之间的连接(多对多关系),但是连接使用非标准外键。我的第一个想法是创建一个名为TvShowEpisodeLink的模型,但没有主键。我的想法是,由于外键是非标准的,我可以使用set_foreign_key并进行一些控制。最后,我想说一些类似TvShow.find(:last).episodes或Episode.find(:last).tv_sho

  10. ruby - rails 3.2.2(或 3.2.1)+ Postgresql 9.1.3 + Ubuntu 11.10 连接错误 - 2

    我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat

随机推荐