{"id":4388,"date":"2013-02-22T14:59:41","date_gmt":"2013-02-22T22:59:41","guid":{"rendered":"http:\/\/www.krunk4ever.com\/blog\/?p=4388"},"modified":"2013-04-22T00:24:33","modified_gmt":"2013-04-22T07:24:33","slug":"bluetoothadapter-getdefaultadapter-throws-runtimeexception-cant-create-handler-inside-thread-that-has-not-called-looper-prepare","status":"publish","type":"post","link":"https:\/\/www.krunk4ever.com\/blog\/2013\/02\/22\/bluetoothadapter-getdefaultadapter-throws-runtimeexception-cant-create-handler-inside-thread-that-has-not-called-looper-prepare\/","title":{"rendered":"BluetoothAdapter.getDefaultAdapter() throws RuntimeException: Can&#8217;t create handler inside thread that has not called Looper.prepare()"},"content":{"rendered":"<p>So I&#8217;m using some hardware SDK that attempts to scan for bluetooth devices on Android and hit into this exception below when calling: <code>BluetoothAdapter.getDefaultAdapter()<\/code><\/p>\n<p><code>Caused by: java.lang.RuntimeException: <strong>Can't create handler inside thread that has not called Looper.prepare()<\/strong><br \/>\n&nbsp; &nbsp; at android.os.Handler.&lt;init&gt;(Handler.java:121)<br \/>\n&nbsp; &nbsp; at android.bluetooth.BluetoothAdapter$1.&lt;init&gt;(BluetoothAdapter.java:984)<br \/>\n&nbsp; &nbsp; at android.bluetooth.BluetoothAdapter.&lt;init&gt;(BluetoothAdapter.java:984)<br \/>\n&nbsp; &nbsp; at android.bluetooth.BluetoothAdapter.getDefaultAdapter(BluetoothAdapter.java:329)<\/code><\/p>\n<p>After researching this problem, it turns out there&#8217;s a bug in Android (which apparently still exists in Android 4.0: Ice Cream Sandwich according to the discussions I&#8217;ve been reading). The bug is during the initialization of the default adapter, there exists UI code which means it needs to be ran on the UI thread.<\/p>\n<p><ins datetime=\"2013-04-22T07:22:38+00:00\">Update 2013\/04\/22<\/ins>: Martin has brought to my attention that as long as you call <code>BluetoothAdapter.getDefaultAdapter()<\/code> inside any thread that has already called <code>Looper.prepare()<\/code>, it should work. It doesn&#8217;t have to be the UI thread.<\/p>\n<p>I was attempting to use <code>AsyncTask<\/code> to search for bluetooth devices in the background. Workaround suggest running the code in the main thread or using <code>Handler<\/code> so that code is queued in the main thread. Unfortunately both solutions block the UI thread and what you see is a progress dialog with a spinner that stops spinning.<\/p>\n<p>It turns out however if you call <code>BluetoothAdapter.getDefaultAdapter()<\/code> in the main UI thread, calling it subsequently no longer crashes, even in background threads.<\/p>\n<p>Hope that helps!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So I&#8217;m using some hardware SDK that attempts to scan for bluetooth devices on Android and hit into this exception below when calling: BluetoothAdapter.getDefaultAdapter() Caused by: java.lang.RuntimeException: Can&#8217;t create handler inside thread that has not called Looper.prepare() &nbsp; &nbsp; at android.os.Handler.&lt;init&gt;(Handler.java:121) &nbsp; &nbsp; at android.bluetooth.BluetoothAdapter$1.&lt;init&gt;(BluetoothAdapter.java:984) &nbsp; &nbsp; at android.bluetooth.BluetoothAdapter.&lt;init&gt;(BluetoothAdapter.java:984) &nbsp; &nbsp; at android.bluetooth.BluetoothAdapter.getDefaultAdapter(BluetoothAdapter.java:329) After researching &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.krunk4ever.com\/blog\/2013\/02\/22\/bluetoothadapter-getdefaultadapter-throws-runtimeexception-cant-create-handler-inside-thread-that-has-not-called-looper-prepare\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;BluetoothAdapter.getDefaultAdapter() throws RuntimeException: Can&#8217;t create handler inside thread that has not called Looper.prepare()&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[12],"tags":[1469,1470],"_links":{"self":[{"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/posts\/4388"}],"collection":[{"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/comments?post=4388"}],"version-history":[{"count":0,"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/posts\/4388\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/media?parent=4388"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/categories?post=4388"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.krunk4ever.com\/blog\/wp-json\/wp\/v2\/tags?post=4388"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}