Android Question Astreams, serial and Bluetooth - disconnect

Discussion in 'Android Questions' started by Arf, Mar 26, 2015.

  1. Arf

    Arf Active Member Licensed 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:
    Code:
    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.
     
  2. Arf

    Arf Active Member Licensed 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.
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    Which error do you get when calling AStreams.Close?
     
  4. Arf

    Arf Active Member Licensed 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: Jan 26, 2016
  5. Arf

    Arf Active Member Licensed 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: Jan 26, 2016
  6. Erel

    Erel Administrator Staff Member Licensed User

    Are you sure that your timer doesn't close the connection multiple times? You can add a Try / Catch block to catch this error.
     
  7. Arf

    Arf Active Member Licensed 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:
    Code:
    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
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    You cannot reconnect right away because you are disabling the bluetooth adapter.
     
  9. Arf

    Arf Active Member Licensed 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.
     
  10. Arf

    Arf Active Member Licensed 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:
    Code:
    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.
     
  11. SteveTerrell

    SteveTerrell Active Member Licensed User


    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.
     
  12. Arf

    Arf Active Member Licensed 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.
     
  13. SteveTerrell

    SteveTerrell Active Member Licensed User

    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!
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice