Android Question Astreams, serial and Bluetooth - disconnect

Arf

Well-Known Member
Licensed User
Longtime User
I understand the B4A bridge uses a heartbeat approach to monitor whther bluetooth connection has been broken, so I'm wondering in knowledge of how that works can help me.

My handheld bluetooth product can be turned off at any time. The module inside it supports a 'Disconnect' packet, which I send just before the product powers down. Obviously when it powers down, the bluetooth radio turns off so the connection is well and truly interrupted.

I detect that the product has been powered down when I see I have not received a 'heartbeat' packet on the tablet for over 500ms. If I had to wait for the Astreams_Error to spring instead, that takes about 10 seconds - too long for me.

Anyhow, when I detect a lack of heartbeat what I do is try to disconnect everything in the comms path, disable then re-enable the bluetooth and re-init and listen again. Works well in practice on most tablets, but crashes the application on the newer HUDL tablet, which has bluetooth 4.0.

My de-init everything strategy (when heartbeat disappears) is like this:
B4X:
    AStream.Close
    admin.CancelDiscovery
    serial1.Disconnect
    admin.Disable

I always get an exception when performing the first thing - Astream.Close. In the case of the HUDL, this is where the app stops working.

So my question is:
is there a logical order to the way I do those disconnects and things or some events I should wait for after doing any of them before proceeding to the next that would help me avoid the exception?

I think actually I do not need to disconnect the bluetooth and reboot it, I get the feeling that if I could just get Astream to close without throwing an exception, the thing would work optimally.
 

Arf

Well-Known Member
Licensed User
Longtime User
So I read that the right way to do the Astreams.Close without getting an exception is to wait for the Astreams_Error event and then it's done automatically, so I guess that means a 10 second wait no matter what. What I was wondering was, if I terminated the serial connection or did something with bluetooth admin that might force a quicker Astreams_Error, then that might be the way forward. Will experiment some more at any rate.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
This one:
java.lang.NullPointerException
at android.bluetooth.BluetoothSocket.close(BluetoothSocket.java:465)
at android.bluetooth.BluetoothInputStream.close(BluetoothInputStream.java:44)
at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.close(AsyncStreams.java:288)
at anywheresoftware.b4a.randomaccessfile.AsyncStreams.Close(AsyncStreams.java:150)
at SpConnect.Home.unit_comms._timer1_tick(unit_comms.java:1752)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5097)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:610)
at dalvik.system.NativeStart.main(Native Method)
 
Last edited:
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
In fact that's whats in the catlog when the debugger halts when hitting Astreams close, that might not be what's causing the app to stop. If I hit RUN on the debugger from there it crashes, but not before appending these additions to the catlog:

java.lang.RuntimeException: java.lang.NullPointerException
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:213)
at anywheresoftware.b4a.objects.Timer$TickTack.run(Timer.java:105)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5097)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:610)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.bluetooth.BluetoothSocket.close(BluetoothSocket.java:465)
at android.bluetooth.BluetoothInputStream.close(BluetoothInputStream.java:44)
at anywheresoftware.b4a.randomaccessfile.AsyncStreams$AIN.close(AsyncStreams.java:288)
at anywheresoftware.b4a.randomaccessfile.AsyncStreams.Close(AsyncStreams.java:150)
at SpConnect.Home.unit_comms._timer1_tick(unit_comms.java:1752)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
... 10 more
** Activity (main) Resume **
 
Last edited:
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Yes, I disable the timer in the Tick function.
I tried adding a try -catch (please look below, perhaps I should do more in the catch bit) but what happens is I get the logged exception, but then I cannot reconnect the bluetooth again right away as I can without the try-catch.
So on most tablets without the try-catch I can see a logcat error but the app continues running, but on this HUDL with bluetooth 4.0 the app crashes. I'll double check what the hudl does with the try-catch in a moment. Here's my tick function:
B4X:
Sub Timer1_Tick
    If TIMEOUT = True Then
        'we need to actively terminate the bluetooth connection and start listening again
        'ToastMessageShow("discon detected - reboot BT",False)
        UNIT_CONNECTED = False
        GOT_BATVOLT = False
        Timer1.Enabled = False
        'Try
            AStream.Close
        'Catch
        '    Log(LastException.Message)
        'End Try
        admin.CancelDiscovery
        serial1.Disconnect
        admin.Disable
        StreamingPulses = False
        CallSub(ForcedTest,"Timer2Enable")
    End If
    TIMEOUT = True   
End Sub
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
I don't mean right away - on most devices when that disconnect occurs, I disable the bluetooth adaptor, then the Timer2 enables BT again after about a second. It takes approx 2 or 3 seconds before I can reconnect. Works great on samsung S3 phone, S3 7in tablet, nexus 7, nexus 10.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
It's Fixed!!!! Oh my word, this has been bugging me for over a year now, and now it's behaving :)
I added the try-catch back in as in my post above, this stops the crash but I could not re-connect afterwards like I normally can (after re-enabling the bluetooth).
In my Serial_Connected function I had this:
B4X:
If AStream.IsInitialized = False Then
            AStream.Initialize(serial1.InputStream, serial1.OutputStream, "AStream")
End If

Removing the InInitialised test and just initialising the Astream again no matter what brought the reconnection back.
This is such a good thing to occur on a Friday, I've worried about it for such a long time.
 
Upvote 0

SteveTerrell

Active Member
Licensed User
Longtime User
It's Fixed!!!! Oh my word, this has been bugging me for over a year now, and now it's behaving :)
I added the try-catch back in as in my post above, this stops the crash but I could not re-connect afterwards like I normally can (after re-enabling the bluetooth).
In my Serial_Connected function I had this:
B4X:
If AStream.IsInitialized = False Then
            AStream.Initialize(serial1.InputStream, serial1.OutputStream, "AStream")
End If

Removing the InInitialised test and just initialising the Astream again no matter what brought the reconnection back.
This is such a good thing to occur on a Friday, I've worried about it for such a long time.


Hi Arf,
That is interesting information, thanks for sharing.
One thing I have noticed on the Nexus 7 with Lollipop is that it can be a problem to try serial1.Connect... straight after a serial1.Disconnect. Waiting a few seconds after the disconnect seems to help. If i do not do that i often get the failure to connect error.
I know that is not your problem but it is something I have found and may be of interest to you.
 
Upvote 0

Arf

Well-Known Member
Licensed User
Longtime User
Thanks Steve, I've just checked it on on the nexus7 with lollipop - it's nice and solid.
In my case I never do a serial1 connect, the tablet is always listening and my handheld product is configured with an autoconnect to the tablet MAC on powerup.
So basically I can tun my product on, it connects to the tablet within 3 seconds of powerup, then when I turn the product off the tablet app informs me within 500ms that the product is not connected, and if I turn the product back on, I am reconnected within another 3 seconds.

I can't tell you how many hours I've spent trying to get that to work with no exceptions on the multitude of devices I've got. Champagne tonight methinks :)

I'll post my code snippets and strategy in due course in case it's of use to anyone.

Another question for you though - has lollipop slowed your nexus7 down ridiculously compared to KitKat? Mine is certainly sluggish.
 
Upvote 0

SteveTerrell

Active Member
Licensed User
Longtime User
Thanks Steve, I've just checked it on on the nexus7 with lollipop - it's nice and solid.
In my case I never do a serial1 connect, the tablet is always listening and my handheld product is configured with an autoconnect to the tablet MAC on powerup.
So basically I can tun my product on, it connects to the tablet within 3 seconds of powerup, then when I turn the product off the tablet app informs me within 500ms that the product is not connected, and if I turn the product back on, I am reconnected within another 3 seconds.

I can't tell you how many hours I've spent trying to get that to work with no exceptions on the multitude of devices I've got. Champagne tonight methinks :)

I'll post my code snippets and strategy in due course in case it's of use to anyone.

Another question for you though - has lollipop slowed your nexus7 down ridiculously compared to KitKat? Mine is certainly sluggish.

I have a HUDL 2 which is still on KitKat and it does seem faster and more reliable (on Bluetooth) than the Nexus. Could be the hardware I suppose. The Nexus Bluetooth does seem less reliable on Lollipop than it was on KitKat (in my case failure to connect and occasional unexpected disconnects).

I look forward to seeing any code snippets. Hope you have recovered from the Champagne!
 
Upvote 0
Top