为什么某些设备上的 Android 蓝牙接收存在延迟问题。

huangapple go评论73阅读模式
英文:

Why Android Bluetooth receive lagging on certain devices

问题

最近在对最新的三星Tab A 8.0(SM-T290)和联想M7(TB-7305F)(均运行Android v9)进行测试时,连接到某些设备时接收到的蓝牙数据出现延迟。在旧版平板电脑和连接到相同设备的手机上运行相同的应用程序时,没有任何问题。在某些较新的手机上运行相同的应用程序也没有问题。

似乎在出现问题的设备上,InputStream 似乎会缓冲更多数据,而不是立即更新套接字读取。并且往往会阻塞近乎完整的 BUFFER_SIZE。而在没有问题的设备上,新数据几乎会立即返回。

大致的接收代码如下:

	private static final int BUFFER_SIZE = 1024;
	private OutputStream tx;
	private InputStream rx;
	private BluetoothSocket bt_socket;

    public void run() {

		BluetoothDevice device = getDevice();
		if (device != null) {
			// create socket
			try {
				bt_socket = device.createInsecureRfcommSocketToServiceRecord(UUID_BLUETOOTH_SERIAL);

				bt_socket.connect();

				tx = bt_socket.getOutputStream();
				rx = bt_socket.getInputStream();

				nativeBluetoothStatusNotify(deviceName, FLAG_CONNECTED);
			} catch (IOException e) {

				try {
					bt_socket.close();
				} catch (IOException closeException) {
				}
				nativeBluetoothStatusNotify(deviceName, FLAG_CONNECTION_FAILED);
			}

			try {
				while (true) {
					int bytesRead = rx.read(buffer, 0, BUFFER_SIZE);
					String cOut = new String(buffer, 0, bytesRead, "ISO-8859-1");
					nativeBluetoothRxNotify(deviceName, buffer, cOut.length());
				}
			} catch (IOException e) {
				nativeBluetoothStatusNotify(deviceName, FLAG_RECEIVE_FAILED);
			} catch (NullPointerException e) {
				nativeBluetoothStatusNotify(deviceName, FLAG_BLUETOOTH_FAILURE);
			}
		}
	}

减小 BUFFER_SIZE 确实在很大程度上有所帮助,但数据仍然会出现断断续续和延迟的情况。

是否有人可以就此提供一些见解或任何解决方法?这是否是 Android 本身、我的实现还是底层蓝牙固件中的问题?

英文:

Recently when testing with the latest Samsung Tab A 8.0 (SM-T290) and Lenovo M7 (TB-7305F) (Both running Android v9), the bluetooth data being received is lagging when connected to certain devices. Running the same app on older tablets and phones connecting to same devices have no issues. Running the same app on some newer phones also have no issues.

It seems the InputStream on these devices with issues seems to buffer more data, instead of updating the socket read straight away. And tends to block for nearly the full BUFFER_SIZE. Where as on devices without issues, new data is returned nearly straight away.

Rough receive code as follows:

private static final int BUFFER_SIZE = 1024;
private OutputStream tx;
private InputStream rx;
private BluetoothSocket bt_socket;

public void run() {

	BluetoothDevice device = getDevice();
	if (device != null) {
		// create socket
		try {
			bt_socket = device.createInsecureRfcommSocketToServiceRecord(UUID_BLUETOOTH_SERIAL);

			bt_socket.connect();

			tx = bt_socket.getOutputStream();
			rx = bt_socket.getInputStream();

			nativeBluetoothStatusNotify(deviceName, FLAG_CONNECTED);
		} catch (IOException e) {

			try {
				bt_socket.close();
			} catch (IOException closeException) {
			}
			nativeBluetoothStatusNotify(deviceName, FLAG_CONNECTION_FAILED);
		}

		try {
			while (true) {
				int bytesRead = rx.read(buffer, 0, BUFFER_SIZE);
				String cOut = new String(buffer, 0, bytesRead, "ISO-8859-1");
				nativeBluetoothRxNotify(deviceName, buffer, cOut.length());
			}
		} catch (IOException e) {
			nativeBluetoothStatusNotify(deviceName, FLAG_RECEIVE_FAILED);
		} catch (NullPointerException e) {
			nativeBluetoothStatusNotify(deviceName, FLAG_BLUETOOTH_FAILURE);
		}
	}
}

Reducing the BUFFER_SIZE does help quite a lot, but the data still comes in choppy and delayed.

Can anyone provide some insight on this or any work around? Is this something in Android itself, my implementation or the underlying bluetooth firmware?

答案1

得分: 2

我最终通过简单地确保偶尔向那些设备发送数据来解决了这个问题,而不是在启动时进行配置,然后只是静静地接收。每隔500毫秒发送一个单独的心跳字符(换行符)似乎是最基本的修复方法,可以解决这个问题。

我怀疑那些出现问题的平板电脑在一段时间内没有发送数据时可能会进入某种蓝牙扫描/广告模式,或者可能会进入低功耗模式;这会减缓接收速度。

英文:

I ended up solving this issue by simply making sure I was sending data occasionally to those devices, instead of configuring on startup then just sitting receiving. A single heartbeat char (linefeed) every 500ms seemed the most basic fix which addressed the issue.

I suspect those tablets with issues must go into some bluetooth scan/advertise mode, or maybe low power when not sending for a period of time; which slows down receiving.

huangapple
  • 本文由 发表于 2020年8月19日 19:13:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63485758.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定