- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我已成功与蓝牙设备配对并连接。我现在有兴趣接收在 2 之间传输的所有数据并查看是什么。
我正在从套接字获取输入流并尝试读取它。我退回并记录它。
根据我所读的内容,我知道这样做的唯一方法就是使用字节缓冲区进行读取以返回一个 int。但是我应该有大量数据通过。我怎样才能连续读出正在传输的数据,并将格式设置为字节而不是 int。
谢谢。
完整代码如下:
public class ConnectThread {
private BluetoothSocketWrapper bluetoothSocket;
private BluetoothDevice device;
private boolean secure;
private BluetoothAdapter adapter;
private List<UUID> uuidCandidates;
private int candidate;
/**
* @param device the device
* @param secure if connection should be done via a secure socket
* @param adapter the Android BT adapter
* @param uuidCandidates a list of UUIDs. if null or empty, the Serial PP id is used
*/
public ConnectThread(BluetoothDevice device, boolean secure, BluetoothAdapter adapter,
List<UUID> uuidCandidates) {
this.device = device;
this.secure = secure;
this.adapter = adapter;
this.uuidCandidates = uuidCandidates;
if (this.uuidCandidates == null || this.uuidCandidates.isEmpty()) {
this.uuidCandidates = new ArrayList<UUID>();
this.uuidCandidates.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
}
}
public BluetoothSocketWrapper connect() throws IOException {
boolean success = false;
while (selectSocket()) {
adapter.cancelDiscovery();
try {
bluetoothSocket.connect();
success = true;
break;
} catch (IOException e) {
//try the fallback
try {
bluetoothSocket = new FallbackBluetoothSocket(bluetoothSocket.getUnderlyingSocket());
Thread.sleep(500);
bluetoothSocket.connect();
success = true;
break;
} catch (FallbackException e1) {
Log.w("BT", "Could not initialize FallbackBluetoothSocket classes.", e);
} catch (InterruptedException e1) {
Log.w("BT", e1.getMessage(), e1);
} catch (IOException e1) {
Log.w("BT", "Fallback failed. Cancelling.", e1);
}
}
}
if (!success) {
throw new IOException("Could not connect to device: "+ device.getAddress());
}
receiveData(bluetoothSocket);
return bluetoothSocket;
}
private boolean selectSocket() throws IOException {
if (candidate >= uuidCandidates.size()) {
return false;
}
BluetoothSocket tmp;
UUID uuid = uuidCandidates.get(candidate++);
Log.i("BT", "Attempting to connect to Protocol: "+ uuid);
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(uuid);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(uuid);
}
bluetoothSocket = new NativeBluetoothSocket(tmp);
return true;
}
public static interface BluetoothSocketWrapper {
InputStream getInputStream() throws IOException;
OutputStream getOutputStream() throws IOException;
String getRemoteDeviceName();
void connect() throws IOException;
String getRemoteDeviceAddress();
void close() throws IOException;
BluetoothSocket getUnderlyingSocket();
}
public static class NativeBluetoothSocket implements BluetoothSocketWrapper {
private BluetoothSocket socket;
public NativeBluetoothSocket(BluetoothSocket tmp) {
this.socket = tmp;
}
@Override
public InputStream getInputStream() throws IOException {
return socket.getInputStream();
}
@Override
public OutputStream getOutputStream() throws IOException {
return socket.getOutputStream();
}
@Override
public String getRemoteDeviceName() {
return socket.getRemoteDevice().getName();
}
@Override
public void connect() throws IOException {
socket.connect();
}
@Override
public String getRemoteDeviceAddress() {
return socket.getRemoteDevice().getAddress();
}
@Override
public void close() throws IOException {
socket.close();
}
@Override
public BluetoothSocket getUnderlyingSocket() {
return socket;
}
}
public class FallbackBluetoothSocket extends NativeBluetoothSocket {
private BluetoothSocket fallbackSocket;
public FallbackBluetoothSocket(BluetoothSocket tmp) throws FallbackException {
super(tmp);
try
{
Class<?> clazz = tmp.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[] {Integer.TYPE};
Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[] {Integer.valueOf(1)};
fallbackSocket = (BluetoothSocket) m.invoke(tmp.getRemoteDevice(), params);
}
catch (Exception e)
{
throw new FallbackException(e);
}
}
@Override
public InputStream getInputStream() throws IOException {
return fallbackSocket.getInputStream();
}
@Override
public OutputStream getOutputStream() throws IOException {
return fallbackSocket.getOutputStream();
}
@Override
public void connect() throws IOException {
fallbackSocket.connect();
}
@Override
public void close() throws IOException {
fallbackSocket.close();
}
}
public static class FallbackException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public FallbackException(Exception e) {
super(e);
}
}
public void sendData(BluetoothSocketWrapper socket, int data) throws IOException{
ByteArrayOutputStream output = new ByteArrayOutputStream(4);
output.write(data);
OutputStream outputStream = socket.getOutputStream();
outputStream.write(output.toByteArray());
}
public int receiveData(BluetoothSocketWrapper socket) throws IOException{
byte[] buffer = new byte[256];
ByteArrayInputStream input = new ByteArrayInputStream(buffer);
InputStream inputStream = socket.getInputStream();
inputStream.read(buffer);
return input.read();
}
}
最佳答案
首先,停止使用 ByteArrayInputStream
和 ByteArrayOutputStream
以获得更多控制。
如果套接字发送/接收文本,执行此操作。
发送:
String text = "My message";
socketOutputStream.write(text.getBytes());
接收:
int length = socketInputStream.read(buffer);
String text = new String(buffer, 0, length);
socketOutputStream
应该是您的 bluetoothSocket.getOutputStream()
。
如果套接字发送/接收大量数据,关键是while循环防止内存不足异常。数据将按 block (例如每 4KB 缓冲区大小)读取,当您选择缓冲区大小时,请考虑堆大小,如果您是直播媒体,还要考虑延迟和质量。
发送:
int length;
while ((length = largeDataInputStream.read(buffer)) != -1) {
socketOutputStream.write(buffer, 0, length);
}
接收:
int length;
//socketInputStream never returns -1 unless connection is broken
while ((length = socketInputStream.read(buffer)) != -1) {
largeDataOutputStream.write(buffer, 0, length);
if (progress >= dataSize) {
break; //Break loop if progress reaches the limit
}
}
常见问题解答:
largeDataInputStream
和 largeDataOutputStream
?这些流可以是普通的 I/O 流、FileInputStream
/FileOutputStream
等。BluetoothSocket
的 while 循环永远不会结束?套接字输入持续接收数据,read()
方法会阻塞自身,直到检测到数据。为防止阻塞该行中的代码,必须中断 while 循环。注意:此答案可能需要修改。我的母语不是英语。
关于java - Android:蓝牙 - 如何读取传入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44593085/
是否可以识别我周围启用了蓝牙的设备?我不需要与他们交流,只知道他们就在那里。 我正在寻找类似于 android 的 BluetouthDevice.startDiscovery() 的东西 这样的事情
蓝牙的 HTTP 代理服务是否允许我将 BLE 设备视为 HTTP 服务器,例如以便与设备对话的应用可以向其发送 GET/POST/PUT 请求? 或者这个操作是相反的方向,BLE 设备通过应用程序向
我正在与BlueZ库一起在Linux下管理蓝牙堆栈。我正在尝试打开一个套接字,该套接字应与已知UUID的特定服务连接。我已成功尝试按照以下示例在服务器和客户端之间打开套接字: http://peopl
有谁知道蓝牙设备如何获取范围内可发现设备的设备 ID? 理想情况下,我正在寻找涉及蓝牙协议(protocol)最小实现的最简单解决方案。 一个起点会很好,我只是想创建一个设备,它可以以最小的功耗存储附
蓝牙双模设备是否可以在与 BT LE 设备配对的同时被经典蓝牙发现?如果设备不能同时运行这两种模式也没关系,但我真的应该在这些模式之间切换芯片吗?我只是在 BT 4 Core 规范中找不到答案 最佳答
我目前正在开展一个涉及乐高 Mindstorms 套件的项目。砖 block 是 NXT,我对蓝牙 ping 速率很好奇。 我对其进行了 100 次 ping 测试,得到了一些有趣的结果。延迟似乎分为
我正在启动一个通过蓝牙进行无线 MIDI 连接的项目。据我所知,BT规范中没有定义MIDI配置文件。 我想知道你们中的一些人是否有兴趣分享有关通过 BT 使用 MIDI 的最佳方式的经验,特别是关于延
Closed. This question is off-topic。它当前不接受答案。
我想通过蓝牙将我的摩托罗拉机器人连接到 OBDKey。我以 BluetoothChat 为例连接蓝牙,使用 KWP 作为协议(protocol) 然后我写byte[]命令 command[0]=ra
几个月前,我用 C# 编写了一个 Messenger 程序,可以让许多客户端连接到服务器并进行聊天。 现在,我想为 android 编写相同的程序。在阅读了 Android Developers 中的
我目前正在制作一个与蓝牙相关的 Android 实用程序,我需要更改我的设备的设备发现范围.. 我有办法这样做吗?我目前正在考虑使用 TPL 来执行此操作,但我不太确定.. Android 应用程序或
我正在为两个玩家构建 tic tac,需要蓝牙连接来交换一些数据,我可以启用蓝牙,启用发现能力,但我不知道“BluetoothServerSocket”和客户端“BluetoothSocket”中的问
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visi
我正在 Microsoft visual studio express 2012,C++ 中制作一个程序,以便与具有此 mac 地址的设备建立简单的蓝牙连接:“00:12:08:24:15:50”,
我正在为 python import bluetooth 使用蓝牙模块,我相信它是 PyBluez 包。我能够从 bluetooth.BluetoothSocket 类进行连接、发送和接收,但我的应用
我正在为 python import bluetooth 使用蓝牙模块,我相信它是 PyBluez 包。我能够从 bluetooth.BluetoothSocket 类进行连接、发送和接收,但我的应用
我尝试通过以下命令来做到这一点: ./configure -developer-build -opensource -nomake examples -nomake tests make module
我有一个服务,理论上可以在没有关联 Activity 的情况下工作(因为“服务”适用于 Android 平台)。 此服务使用蓝牙,特别是注册一个具有给定名称的蓝牙服务来监听通信。当然,它必须启用蓝牙才
谁知道是否可以制作一个应用程序通过蓝牙模拟触摸屏鼠标或触控板? 如何让 PC(或 MAC)知道我是鼠标设备? 问候, 胡安 最佳答案 您应该看看蓝牙 HID 规范。这可能是可能的,具体取决于您用来模拟
我的问题很简单。我想知道什么是我的应用程序的最佳实践,以便它可以“防打瞌睡”。随着 Android N 将在更多情况下应用 Doze,这变得更加相关。 阅读时Doze Documentation有一部
我是一名优秀的程序员,十分优秀!