I’m working on an app using Bluetooth discovery pretty heavily (some detail here). The nature of the app is that I’m pretty much keeping the BT always on and waiting around for changes in BT names from some broadcasting devices. Power usage is not an issue since my device is permanently charging.
I’ve found that at certain times my app “loses the thread” and doesn’t discover anything on BT, even though BT is turned on, and there are devices in range. In a manual way, I can solve this by turning the BT off and on on the device – presto! It works again. So I wanted to do this in code. I have a whole timeout timer, which sends a message to a handler:
bluetoothHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (!btAdapter.isDiscovering())
{
btAdapter.disable();
btAdapter.enable();
btAdapter.startDiscovery();
// some other stuff
}
Well, this code seems to sometimes crash with a null pointer exception on the “disable” line
Here’s the ACRA info:
"java.lang.NullPointerException
at android.os.Parcel.readException(Parcel.java:1328)
at android.os.Parcel.readException(Parcel.java:1276)
at android.bluetooth.IBluetooth$Stub$Proxy.disable(IBluetooth.java:604)
at android.bluetooth.BluetoothAdapter.disable(BluetoothAdapter.java:562)
at com.myapp.stuff.MainActivity$8.handleMessage(MainActivity.java:574)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
As you can see, it doesn’t make sense that the btAdapter is really null otherwise we would have crashed on the line before (the “if”) – and even assuming the code is reentrant, I don’t ever null the btAdapter in my code at any point – I set it in OnCreate and leave it forever so how does it get to be null?
I saw a couple of people posting that they got NullPointerException doing code with enable/disable – and suggestions to use Intents to start/stop Bluetooth – this is not an option here – there is no user intervention – the user (if they want this rather specialized app to work) needs the BT to be running (and if not running right to be fixed) automatically.
I’m assuming I can’t put a try/catch around a NullPointerException (even though it is bogus) – does anyone know enough about the Bluetooth internals to figure out why disable is crashing on me?
Well, I don’t really understand what was going wrong, but my fix was fairly simple and stupid:
Instead of leaving the one value around for btAdapter I check it each time before using it and try/catch for any exception (though i assume this wouldn’t capture a REAL null pointer)
So every time I cll disable (which was crashing) I do this