当我试图获取默认蓝牙适配器时我不在活动中,而是在TimerTask
(在Service
内创建)使用:
BluetoothAdapter.getDefaultAdapter();
我得到以下异常:
Exception while invoking java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
我的应用程序没有任何活动 - 所以有没有可能让这个适配器远离Activity?
答案 0 :(得分:14)
这似乎是Android中的一个错误,仍然存在于Android 4.0(冰淇淋三明治)
中要解决此问题并且能够从工作线程(例如AsyncTask)调用BluetoothAdapter.getDefaultAdapter()
,您只需在主UI线程上调用BluetoothAdapter.getDefaultAdapter()
一次(例如{{1}内部您目前的活动)。
RuntimeException仅在初始化期间抛出,onCreate()
仅在您第一次调用它时初始化。即使在后台线程中,对它的后续调用也会成功。
答案 1 :(得分:6)
在BluetoothAdapter.getDefaultAdapter()
帖子中调用UI
有效,但不太实际。我已尝试使用假活动的解决方法,但由于我讨厌这样的解决方法,我决定阅读错误消息的真实内容,而这只不过是线程没有调用Looper.prepare()
。
所以在调用Looper.prepare()
之前调用BluetoothAdapter.getDefaultAdapter()
应该可以在任何地方解决问题,而不仅仅是在UI线程中。
到目前为止对我来说没问题。
答案 2 :(得分:3)
不确定它是多么正确,但我添加了这个包装函数:
static boolean m_calledLooperAlready = false;
BluetoothAdapter getDefaultBluetoothAdapter() {
if ( !m_calledLooperAlready ) {
try {
android.os.Looper.prepare();
} catch ( RuntimeException e ) { e.printStackTrace(); }
m_calledLooperAlready = true;
}
return BluetoothAdapter.getDefaultAdapter();
}
...并将所有BluetoothAdapter.getDefaultAdapter()
替换为getDefaultBluetoothAdapter()
。这适用于我:2.2.1,2.3.3,4.0.4,4.3
答案 3 :(得分:1)
谨防2.3.x中存在的问题,但已在4.x中修复:如果在主应用程序线程以外的任何线程上调用BluetoothAdapter.getDefaultAdapter()
,该线程必须调用{{1}随后Looper.prepare()
。
如果不这样做会导致我遇到至少一个问题:Looper.loop()
会在您第一次尝试连接时成功,但是在连续尝试后都不会成功,即使在使用accept()
之后也是如此ServerSocket。
这是因为在较旧的BluetoothAdapter实现中,SDP条目的清理是通过发布到在调用close()
的线程上创建的处理程序的消息发生的。
答案 4 :(得分:0)
您好Kocus在getDefault()
中没有任何名为BluetoothAdapter calss
的方法。
它应该是BluetoothAdapter.getDefaultAdapter();