Android Question Bluetooth Reconnection while in Activity

Discussion in 'Android Questions' started by Michael Mc, May 11, 2015.

  1. Michael Mc

    Michael Mc Member Licensed User

    Hello,

    I needs some help from the Android Wizards.

    I'm using a Bluetooth barcode scanner in SPP Mode. If the scanner is ready and I start the Activity everything works fine. But when the scanner timeouts (because of battery saving), I cannot get it to reconnect. I have tried so many different methods to get this to work but still no go.

    I thought I would post my last version of code here and hope that someone can give my their experience to resolve this issue.

    Also, maybe I just missing something here but how do you destroy objects? Example the serial object. I think if you could do this and start over all would be fine.

    Right now where it stands is, if the barcode scanner disconnects, it will try to reconnect and will hit the
    Sub ScanDevice_Connected (Success As Boolean)
    but Success is always False.

    Anyway here is the code. Thank you for your help!

    PS Some old variables may exist in this code that is not used. Please just focus on the primary objects and methods.


    Code:
    #Region  Activity Attributes
        
    #FullScreen: False
        
    #IncludeTitle: True
    #End Region

    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'These variables can be accessed from all modules.

        
    Dim ScanDevice As Serial
        
    Dim Timer1 As Timer

    End Sub

    Sub Globals
        
    'These global variables will be redeclared each time the activity is created.
        'These variables can only be accessed from this module.

        
    Private CloseAppTimer As Int
        
    Private Connected As Boolean
        
    Private WaitingToConnect As Boolean
        
    Private BTNScanQuery As Button
        
    Private ScanIDQuery As EditText
        
    Private WebViewQuery As WebView
        
    Private MyScan As ABZxing
        
    Private StatusPanel As Panel
        
    Private ItemHTMLString As String
        
    Dim ast As AsyncStreamsText
        
    Private WaitingConnectCounter As Int
        
    Dim Toggla As Toggle
      
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        'Activity.LoadLayout("Layout1")
        Log("Activity_Create")
        
    If FirstTime Then
            ScanDevice.Initialize(
    "ScanDevice")
            Timer1.Initialize(
    "Timer1"1000)
        
    End If
        WaitingToConnect=
    False

    Activity.LoadLayout("queryscreen")
    StartScanner(Main.connectedDevice.Name,Main.connectedDevice.mac)  


    WebViewQuery.Color = 
    Colors.Transparent

    If Main.AlphaSKUKeyboard Then
    ScanIDQuery.InputType = ScanIDQuery.INPUT_TYPE_TEXT
    Else
    ScanIDQuery.InputType = ScanIDQuery.INPUT_TYPE_NUMBERS
    End If
    Activity.AddMenuItem("Connect Scanner""mnuConnect")
    Activity.AddMenuItem("Disconnect Scanner""mnuDisconnect")  
    ScanIDQuery.RequestFocus

      
      
    End Sub

    Sub Activity_Resume

        
    Log("Activity_Resume")

         
    If ScanDevice.IsEnabled = False Then
            
    Msgbox("Please enable Bluetooth.""")
            
    Else
            
    If ScanDevice.IsInitialized Then
            ScanDevice.Listen
            
    End If
          
           
    End If
      

    End Sub

    Sub Activity_Pause (UserClosed As Boolean)
        
    Log("Activity_Pause")
        
    End Sub

    Sub StartScanner(Name As String,Mac As String)
    Log("StartScanner " & Name & "  " & Mac)
        
    If Name<>"" Then

        ScanDevice.Connect(
    Mac)
        ScanDevice.Listen
        
    End If
    End Sub



    Sub ScanDevice_Connected (Success As Boolean)
    Log("ScanDevice_Connected" )
        
    If Success Then
            
    ProgressDialogHide
            
    ToastMessageShow("Scanner Connected successfully"False)
            ast.Initialize(Me,
    "ast",  ScanDevice.InputStream, ScanDevice.OutputStream) 'initialize AsyncStreamsText with the socket streams.
            Connected=True
            
    Else
            Connected=
    False
        
    End If
        
    If Timer1.Enabled = False Then     Timer1.Enabled=True  
      
    End Sub
    Sub Timer1_Tick

        
    If Main.BatterySaver =True Then
            CloseAppTimer = CloseAppTimer+
    1
            
    If CloseAppTimer> 600 Then
            
    ' Will enable once everything works.
            '    Activity.Finish
            End If
        
    End If

    If Connected=False  Then
        StartScanner(Main.connectedDevice.Name,Main.connectedDevice.Mac)
    End If

    End Sub


    Sub ast_NewText(Text As String)
      ScanIDQuery.Text =  Text
        ProcessScan
    End Sub


    Sub ast_Terminated
    ScanDevice.Disconnect
      
    ToastMessageShow("Scanner Timeout/Disconnected.",True)
      Connected=
    False
    End Sub
      
    Sub ast_Error
        
    ToastMessageShow(LastException.Message, True)
    End Sub
     
    Last edited: May 11, 2015
  2. Peter Simpson

    Peter Simpson Expert Licensed User

  3. Michael Mc

    Michael Mc Member Licensed User

    Thanks, but that does not reconnect.

    If you start your program it comes up with a blank white screen. Then has connect message try 1 of 5, 2 of 5 and then it connects and I can scans codes.

    But if you turn off the scanner or the scanner timeouts then you turn it back on, it does not attempt to reconnect. The scanner is ready and waiting for a connect from your program.

    I'm not sure if you have any type of disconnect message, I never see anything. If you have programmed any reconnect code it would be great to see what you may have done. Between what you know and I know maybe there is a way to figure this all out. You would think this is a simple issue, because we know when the scanner gets disconnected. Somehow the Serial Object is not happy reconnecting and I have not figured out how to destroy it and create a new one.

    Thanks!!!
     
  4. Peter Simpson

    Peter Simpson Expert Licensed User

    Hmm, what you explained appears to me to be impossible as you must at least tap your screen for the message try 1 of 5, 2 of 5 would even start, it can't start by itself.

    Anyway my app reads from your android device any previously connected Bluetooth devices then shows them to you, you then select your barcode scanner and it should connect. I've just re-uploaded the app just in case it was a previous version, so please try it again.

    Anyway to fix your issue @Michael Mc you should have ScanDevice.Disconnect in Activity_Pause, and ScanDevice.Connect in both Activity_Resume and
    ScanDevice_Connected. The very first time that you connect to the scanner in your app (verify in ScanDevice_Connected), make sure that you store the scanners MAC address in a variable(string) stored in Global, that way when you reconnect in Activity_Resume, you already have the MAC address to hand.

    BTW what barcode scanner are you using?

    That's it...
     
  5. Michael Mc

    Michael Mc Member Licensed User


    Thanks again but no go.

    I do have the MAC address stored in a Global Variable, its Main.connectedDevice.mac.

    I believe the problem is with timing. If I slow my timer down say 1000 instead of 200 I think it is not overloading the message queue and giving the adapter sometime to react. I'm getting better results now, able to connect even from a scanner power off state. I really would want this bullet proof so I guess I'll keep plugging away and see if others have ran into this issue and found a complete solution. I don't want the users to wait to long for the scanner to reconnect.

    Really wish to could just Destroy these objects like other languages and start fresh with new ones when needed.

    I appreciate your help, if you have any discoveries with your project it would be great to share your knowledge to others, including myself :)


    As for the Scanners, I'm testing 2 different ones. Symbol CS3070 and Inateck BCST-10. They both work well but the Symbol is a great pocket size, the Inateck has some nice configuration features.

    Thanks
     
    Last edited: May 11, 2015
  6. Peter Simpson

    Peter Simpson Expert Licensed User

    Okay @Michael Mc first off all you do not need a timer, just testing Success in Sub Scanner_Connected(Success As Boolean) is enough for you to retry connecting if the scanner does not connect first time out. I've noticed that in your code that you are testing if the connection is True, but you are doing nothing when the connection is False.

    Please post a quick example of your project, thank you.

    I take it that you've been to this post http://www.b4x.com/android/forum/threads/barcode-scanning-and-keyboard-input.42000/
     
  7. Michael Mc

    Michael Mc Member Licensed User


    Yes some of those Variables where used when I was playing around, so they are just left over or not really used.

    I need to have the timer event because to auto reconnect there needs to be way to check for a disconnected device and reconnect it when it is back online. I'm not selecting the scanner within the activity, it is established within a different configuration activity.

    Yes I did look at that post, it prompts for you to select a scanner if disconnected. I just need to reconnect the assigned scanner when it becomes online again, don't want to prompt the user because the device may not be within hands reach.

    Thanks again!
     
  8. Peter Simpson

    Peter Simpson Expert Licensed User

    But that's my whole point, you do not need a timer to auto reconnect. All my barcode scanners and my clients barcode scanners reconnect automatically without a timers. Using Activity_Pause and Activity_Resume is enough for the scanner to disconnect and reconnect to the app automatically once you have stored the barcode scanners MAC address on the original connection, even if the phone/tablet is then used for something else, once the user goes back to the app it WILL auto reconnect. You can even scan 100+ barcodes and then go back to the your app afterwards, once auto reconnected the 100+ barcodes will then automatically transfer over one at a time to your app as if you were doing manual scans.

    You do not need a timer, just by adding a
    ScanDevice_Connected into Activity_Resume is enough to reconnect automatically once you have the original MAC address. The prompt is just because there might be more than one scanner used on the device, so prompting is used to interact with the user. Adding the device name programmatically will connect automatically without a prompt.

    Anyway, as I stated in my second post on here to you, you should use Activity_Resume to auto reconnect (check global variable for MAC address) and you should also be using Scanner_Connected(Success As Boolean) and doing something if the scanner is not connected, that's where I put my retry 5 time code. If the scanner turns itself off, then the app will keep trying every few seconds to connect until the scanner is turned back on again. Once again no timer is needed for this to happen if Success = False.

    As I asked previously, please create and post a simple project with your code, just the barcode section and we can then look closer at your issue, but you do not need a timer.
     
    Last edited: May 11, 2015
    thedesolatesoul likes this.
  9. Michael Mc

    Michael Mc Member Licensed User

    Yes I tried what you suggested but it does not reconnect. There is no event being created to have it check to see if the device is online again. So I need something to check it every 10 secs or so. I can Serial.Listen for weeks and nothing gets fired.

    After some trial and error I have my scanners working the way I need them to.

    I think each barcode reader has it's own personality. My Symbol device connects fast the Inateck takes 20 secs or so.


    I do get an error once in awhile after connection has been successful on the ast.Initialize(... line but I think it is timing issue. The ScanDevice (serial stream) must not be completely established prior to assigning the InputStream to the AsyncStreamsText. I'm testing it on a Note 4

    Code:
    Sub ScanDevice_Connected (Success As Boolean)
        
    If Success Then
            
    ProgressDialogHide
            
    ToastMessageShow("Scanner Connected successfully"False)
            
    Try
            ast.Initialize(Me,
    "ast",  ScanDevice.InputStream, ScanDevice.OutputStream)
            
    Catch
              
    End Try
            Connected=
    True
            
    Else
            ScanDevice.Listen
            Connected=
    False
        
    End If
      
    End Sub
    It cannot be a Null Object Reference if it just connected.


    ---------- ERROR -----------------------
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.InputStream android.bluetooth.BluetoothSocket.getInputStream()' on a null object reference
    at anywheresoftware.b4a.objects.Serial.getInputStream(Serial.java:254)
    at com.dscorp.InScan50Standard.queryscreen._scandevice_connected(queryscreen.java:813)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
    at anywheresoftware.b4a.BA$3.run(BA.java:332)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:145)
    at android.app.ActivityThread.main(ActivityThread.java:5972)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
     
  10. Peter Simpson

    Peter Simpson Expert Licensed User

    Hmm interesting, I've not come across the same issues as you, All the Barcode scanners I've connected to (bar one) have worked.
    You should not leave Catch empty, You should use LastException.Message as follows. I use RandomAccessFile for BarcodeData_NewData(Buffer() As Byte) where you're using AsyncStreamText for BarcodeData_NewText(Buffer As String), which really does not matter at all. I've been thinking about your issue but I just cant think of any reason why you would be having issues. Let me drink on it and I'll have a think about your issues @Michael Mc.

    Code:
    Try
         ast.Initialize(Me,
    "ast", ScanDevice.InputStream, ScanDevice.OutputStream)
    Catch
         
    Log(LastException.Message)
    End Try
    I've just changed my code again in my app, it still works for me, if you want to try it out the link is the one in previous posts.
     
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