BluetoothAdapter.getDefaultAdapter()在不在Activity中时抛出RuntimeException

时间:2011-05-07 10:54:34

标签: android bluetooth runtimeexception

当我试图获取默认蓝牙适配器时我不在活动中,而是在TimerTask(在Service内创建)使用:

BluetoothAdapter.getDefaultAdapter();

我得到以下异常:

Exception while invoking java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

我的应用程序没有任何活动 - 所以有没有可能让这个适配器远离Activity?

5 个答案:

答案 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();

follow this link for more information.