- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我基于 bluetoothChat 编写了一个简单的应用程序。我使用 SPP 配置文件在手机和蓝牙模块之间进行通信。电话总是发起通信。该应用程序在 Android 4.2 上完美运行,使用 Nexus 3 和三星 Galaxy 3。更新到 Android 4.3 后,该应用程序不再运行。我一直连接,我可以发送一个 outpustream 并接收正确的数据,但是在第一个 outputstream 命令之后,应用程序总是在大约 6 秒后断开连接。如下面的 logcat 所示,输入流上似乎存在计时器问题。
08-23 14:10:00.726: D/mems(23193): STEVAL-MKI106V1
08-23 14:10:00.804: D/Main Activity(23193): firmware version*setdb106V1
08-23 14:10:00.812: D/Main Activity(23193): sent message*setdb106V1
08-23 14:10:00.812: D/BluetoothMEMSCommunication(23193): dans write3
08-23 14:10:00.812: D/BluetoothMEMSCommunication(23193): envoi stream
08-23 14:10:05.812: W/bt-btif(20368): dm_pm_timer expires
08-23 14:10:05.812: W/bt-btif(20368): dm_pm_timer expires 0
08-23 14:10:05.812: W/bt-btif(20368): proc dm_pm_timer expires
08-23 14:10:11.656: E/bt-btm(20368): btm_sec_disconnected - Clearing Pending flag
08-23 14:10:11.656: W/bt-btif(20368): invalid rfc slot id: 15
08-23 14:10:11.656: I/connection(23193): connectionlost
什么是 dm_pm_timer?我尝试以不同的方式连接,使用安全和不安全的 rfcom。我知道蓝牙聊天没有优化接收缓冲区,所以我修改了它,不是没有效果。我也对 outpustream 使用了 flush 命令,但也没有效果。
package com.meneujj.memsbtbis;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
public class BluetoothMEMSCommunication {
// debugging
private static final String TAG = "BluetoothMEMSCommunication";
private static final boolean D = true;
// eMotion BT h as this standard UUID
private static final UUID STANDARD_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private int mState;
private int handlerCalling;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
// Constants they indicate the current connection state
public static final int STATE_NONE = 0;
public static final int STATE_CONNECTED = 3; // now connected to a remote device
// constructor. Prepares a new Bluetooth Connection
// context The UI Activity Context
// handler an Handler to send messages back to the UI Activity
public BluetoothMEMSCommunication(Context context, Handler handler, int i) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
handlerCalling = i;
}
private synchronized void setState(int state) {
mState = state;
Log.d(TAG, Integer.toString(mState));
mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
public synchronized void connect(BluetoothDevice device) {
// start the thread to connect with the given device
if (mConnectThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
Log.d(TAG,"routine connect lancee");
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
private void ConnectionLost() {
// Send a failure message back to the activity
Message msg = mHandler.obtainMessage(MainActivityMemsBT.CONNECTION_LOST_MESSAGE);
Bundle bundle = new Bundle();
bundle.putString(MainActivityMemsBT.TOAST_CONNECTION_LOST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
Log.i("connection","connectionlost");
setState(STATE_NONE);
StopAllThreads();
}
public synchronized void StopAllThreads() {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
setState(STATE_NONE);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, final String socketType) {
// cancel the thread they completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to manage the connection and perform transmission
mConnectedThread = new ConnectedThread(socket, socketType);
mConnectedThread.start();
// Send the name of the connected device back to the UI activity
Message msg = mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(MainActivityMemsBT.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
public void write(byte[] out) {
// create temporary object
ConnectedThread r;
Log.d(TAG,"dans write" + Integer.toString(mState));
// synchronize a copy of the ConnectedThread
synchronized (this) {
if (handlerCalling == 2) setState(STATE_CONNECTED);
if (mState != STATE_CONNECTED) {
Log.d(TAG, "different de STATE_CONNECTED");
Log.i(TAG, Integer.toString(handlerCalling));
return;}
r= mConnectedThread;
}
r.write(out);
}
知道有解决方法吗?或者我的代码中有任何明显的错误
谢谢
// Thread runs while attempting to an an outgoing connection with a device.
// it runs straight through; the connection either succeeds or fails.
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private String mSocketType;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(STANDARD_UUID);
//tmp = device.createInsecureRfcommSocketToServiceRecord(STANDARD_UUID);
/* try {
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
try {
tmp = (BluetoothSocket) m.invoke(device, 1);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} */
} catch (IOException e) {
}
mmSocket = tmp;
}
public void run () {
setName("ConnectThread" + mSocketType);
mAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException e) {
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() " + mSocketType + "socket during connection failure", e2);
}
return;
}
// reset the CoonectThread because the job is over
synchronized (BluetoothMEMSCommunication.this) {
mConnectThread = null;
}
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
// close connectThread class
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
ConnectionLost();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
// Thread to listen to input sockets
public void run() {
Log.i(TAG, "Begin mConnectedThread");
byte[] buffer = new byte[1024];
// int bytes;
int bytesRead = -1;
String message = "";
// keep listening to the InputStream while connected
while(true) {
try {
// read from the input stream
// bytesRead = mmInStream.read(buffer);
// message = message+ new String(buffer, 0, bytesRead);
// byte[] byteString = message.getBytes();
Log.i("info","pret a faire read");
bytesRead = mmInStream.read(buffer, 0, 1024);
if (bytesRead != -1 && handlerCalling == 1) {
mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_READ, bytesRead, -1, buffer).sendToTarget(); }
if (bytesRead !=-1 && handlerCalling == 2) {
mHandler.obtainMessage(DemoAccelerometer.MESSAGE_READ, bytesRead, -1, buffer).sendToTarget(); }
}
catch (IOException e) {
ConnectionLost();
break;
}
}
}
public void write(byte[] buffer) {
try{
mmOutStream.write(buffer);
// if (handlerCalling == 1) {
// mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
Log.d(TAG,"envoi stream");
// mmOutStream.flush();
// }
} catch (IOException e) {
}
}
public void cancel() {
try{
mmSocket.close();
} catch (IOException e) {
}
}
}
}
最佳答案
从 Android 4.2 升级到 4.3 后,当我们从 Nexus 4 应用程序与外部蓝牙 ECG(医疗设备)通信时,我们可以在 6 秒后确认蓝牙断开连接。这种情况特别发生在有大量入站数据(从 ECG 到 Android 应用程序)但没有出站数据的 ECG 测量期间。 “正常”蓝牙通信不时有一些入站和出站数据似乎没有受到影响。
6 秒后,我们看到 JJM 报告的相同 adb 日志消息
dm_pm_timer expires
dm_pm_timer expires 0
proc dm_pm_timer expires
btm_sec_disconnected - Clearing Pending flag
Android 端的这个计时器到期会触发外部蓝牙 ECG 上的某些东西(因为没有出站数据而关闭输出流?),这反过来会发送我们在输入流上收到的 ECG 特定命令,而我们在 Nexus 4 上从未收到过安卓 4.2。
更改 Android 应用程序实现以偶尔向 ECG 发送任意“保持 Activity 状态”命令可以解决问题。计时器过期不再出现在 adb 日志中,ECG 测量现在的行为与 Android 4.2 相同。
感谢 JJM 的提示。
关于android - 从 Android 4.2 更新到 Android 4.3 后,使用蓝牙 SPP 配置文件的应用程序无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18420525/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!