Android Question EasiBeacon problems

Discussion in 'Android Questions' started by henrywood, Mar 12, 2015.

  1. henrywood

    henrywood Active Member Licensed User

    Hi
    Having read that since Android (contrary to iOS) does not automatically scan for beacons in the background, I am trying to use a Timer with the easibeacon example.

    I am thus trying to modify the example code's Discovery Service.

    This is my code:

    Code:
    #Region  Service Attributes
        
    #StartAtBoot: False
    #End Region

    Sub Process_Globals
        
    Public IBeaconProtocol1 As IBeaconProtocol
        
    Dim ScanTimer As Timer
        
    Dim ScanInterval As Int = 30000
    End Sub

    Sub Service_Create
        
    Dim IBeaconListener1 As IBeaconListener
        IBeaconListener1.Initialize(
    "IBeaconListener1")
        IBeaconProtocol1.Initialize
        IBeaconProtocol1.SetListener(IBeaconListener1)
        ScanTimer.Initialize(
    "ScanTimer", ScanInterval)
        ScanTimer.Enabled = 
    True
      
    End Sub

    Sub Service_Start (StartingIntent As Intent)

    End Sub

    Sub ScanTimer_Tick
        
    ToastMessageShow("Timer tick"False)
        StartScan
    End Sub

    Sub Service_Destroy
        StopScan(
    True)
        
    Dim IBeaconProtocol1 As IBeaconProtocol
    End Sub

    Sub IBeaconListener1_BeaconFound(IBeacon1 As IBeacon)
        
    Log("IBeaconListener1_BeaconFound")
        CallSubDelayed3(Main, 
    "BeaconFound", IBeacon1, True)
    End Sub

    Sub IBeaconListener1_EnterRegion(IBeacon1 As IBeacon)
        
    Log("IBeaconListener1_EnterRegion")
        CallSubDelayed2(Main, 
    "BeaconArriving", IBeacon1)
    End Sub

    Sub IBeaconListener1_ExitRegion(IBeacon1 As IBeacon)
        
    Log("IBeaconListener1_ExitRegion")
        CallSubDelayed2(Main, 
    "BeaconLeaving", IBeacon1)
    End Sub

    Sub IBeaconListener1_OperationError(Status As Int)
        
    Log("IBeaconListener1_OperationError Status="&Status)
    End Sub

    Sub IBeaconListener1_SearchState(State As Int)
        
    Log("IBeaconListener1_SearchState")
        
    Select State
            
    Case IBeaconProtocol1.SEARCH_END_EMPTY
                
    ToastMessageShow("Scan complete - no beacons found"False)
            
    Case IBeaconProtocol1.SEARCH_END_SUCCESS
                
    ToastMessageShow("Scan complete - one or more beacons found"False)
            
    Case IBeaconProtocol1.SEARCH_STARTED
                
    ToastMessageShow("Scan started"False)
        
    End Select
    End Sub

    Sub StartScan
        StopScan(
    False)
        IBeaconProtocol1.StartScan
    End Sub

    Sub StopScan(Reset As Boolean)
        
    If IBeaconProtocol1.IsScanning Then
            IBeaconProtocol1.StopScan
            
    ToastMessageShow("Scan stopped"False)
        
    End If
        
    If Reset Then
            
    '    calling Reset clears any previously found beacons
            IBeaconProtocol1.Reset
        
    End If
    End Sub
    However, I am experiencing three problems:

    1. My timer gets called but the call to StartScan() does not work (ie. it does not re-scan every 30 seconds).
    2. I see an exception (shown as a ToastMessage: libcore.io.ErrnoException: recvfrom failed: ETIMEDOUT (Connection timed out) when using B4ABridge ?
    3. It seems that the ExitRegion handler is never called ??? EnterRegion handler is called though...


    Also, an additional question (I am new to the whole beacon thing):

    - How do I know that the beacon in Enter/ExitRegion Sub is one of my beacons and not somebody else's ?

    Thanks

    /Henrik
     
  2. warwound

    warwound Expert Licensed User

    Take a look at the attached project.
    It's more elaborate than the simple easiBeacons example i posted in the other thread.

    It encapulates the functions of the easiBeacon library into a Class - a single instance of this Class is referenced as a Process Global in the Main Activity module.
    You should be able to modify the project so that instance is referenced as a Process Global of a Service module if desired.

    The project is designed to detect any of 3 easiBeacons i have.
    These 3 easiBeacons have all been configured with the same UUID and the project will only detect easiBeacons with this UUID.

    You could comment out the line in the Main Activity, line 39:

    Code:
    BeaconMonitor1.SetUUIDFilter(<my UUID here>)
    Or you could set the UUID filter to the UUID of your easiBeacon(s).

    My three easiBeacons all have the same Major id of 1, their Minor ids are 1, 2 and 3.

    Configuring your easiBeacons with a unique combination of UUID, Major and Minor ids is the way to know if any found beacons are your own beacons.
    You have to assume that nobody nearby will be using beacons and have them configured with the same UUID that you have chosen - not likely but not impossible...

    The application can scan once or scan repeatedly using a Timer.
    Look in the Class module and you'll see i disable the Timer in it's Tick event, perform a scan and then re-enable the Timer.
    Could your exception be caused by your Timer Tick event being raised while a scan is already in progress?
    Disabling the Timer while a scan is in progress would prevent such an exception.

    So the application performs a scan for beacons and when the scan completes it populates a ListView with all found beacons.
    Displaying the beacon's Major and Minor ids along with their proximity and battery level.
    (Screengrab attached).

    Compile and run the project and look in the log.
    It's pretty self explanatory.
    You'll see comments such as 'BeaconMonitor: callback sub ??? not found'.
    The Class will raise events in the Activity if the corresponding callback sub exists in the Activity.
    If you uncomment these lines in the Activity:

    Code:
    'Sub BeaconMonitor_BeaconFound(IBeacon1 As IBeacon)
    '    this event currently not used
    'End Sub

    'Sub BeaconMonitor_EnterRegion(IBeacon1 As IBeacon)
    '    this event currently not used
    'End Sub

    'Sub BeaconMonitor_ExitRegion(IBeacon1 As IBeacon)
    '    this event currently not used
    'End Sub
    Replace the comment "' this event currently not used" with a Log statement, you should see those callback subs now executed.

    Look at the Class method 'Reset' - see it's comment?
    Calling reset tells the library to forget about any beacons found by it's last scan.
    If these last found beacons are forgotten then the library is unable to raise any 'ExitRegion' events - when it next scans and finds beacons it can't compare the beacons found by the new scan to the (forgotten) beacons found by the previous scan.
    Therefore it cannot know if the android device has exited a region.

    Post again if you have more questions and i'll try and help.

    Martin.
     

    Attached Files:

    DonManfred likes this.
  3. henrywood

    henrywood Active Member Licensed User

    I got it fixed - thanks to all for suggestions

    /Henrik
     
  4. fishwolf

    fishwolf Active Member Licensed User

    where i found the imaginear.api.easibeacon library?

    Thanks
     
  5. warwound

    warwound Expert Licensed User

    DonManfred likes this.
  6. fishwolf

    fishwolf Active Member Licensed User

  7. warwound

    warwound Expert Licensed User

    They are more or less the same...
    I initially developed the easiBeacon library for Imaginear - this library had the java package name imagineear.api.easibeacon.
    Imagineear gave me permission to upload the library to the forum so i recompiled it with a different java package name 'uk.co.martinpearman.b4a.easibeacon'.

    One of the code examples i uploaded was using the Imagineear library so b4a complains that it cannot find 'imaginear.api.easibeacon'.
    You just need to ensure that the Easibeacon library is checked in the library list and save the project - it'll update it's references from 'imaginear.api.easibeacon' to 'uk.co.martinpearman.b4a.easibeacon' and work as expected.

    Martin.
     
    DonManfred likes this.
  8. bioident

    bioident Member Licensed User

    Hi,

    I have a problem application not finf beacons
    I get null object reference:
    uk.co.martinpearman.b4a.easibeacon.IBeaconProtocol.GetIBeaconsByProximity()' on a null object reference

    Please help why:

    LogCat connected to: B4A-Bridge: samsung SM-G900F
    --------- beginning of main
    ** Activity (main) Create, isFirst = true **
    ** Activity (main) Resume **
    ** Service (service1) Create **
    ** Service (service1) Start **
    Connected to B4A-Bridge (Wifi)
    Installing file.
    ** Activity (main) Pause, UserClosed = false **
    PackageAdded: package:b4a.easibeaconsdemo
    Copying updated assets files (3)
    ** Activity (main) Create, isFirst = true **
    ** Activity (main) Resume **
    BeaconMonitor: listener added
    ** Activity (main) Pause, UserClosed = false **
    BeaconMonitor: listener removed
    ** Activity (main) Resume **
    BeaconMonitor: listener added
    ** Activity (main) Pause, UserClosed = false **
    BeaconMonitor: listener removed
    sending message to waiting queue (OnActivityResult)
    running waiting messages (1)
    on result
    ** Activity (main) Resume **
    BeaconMonitor: listener added
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    ** Activity (main) Pause, UserClosed = false **
    BeaconMonitor: listener removed
    ** Activity (main) Resume **
    BeaconMonitor: listener added
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    ** Activity (main) Pause, UserClosed = false **
    BeaconMonitor: listener removed
    ** Activity (main) Resume **
    BeaconMonitor: listener added
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanIdle
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanIdle
    ** Activity (main) Pause, UserClosed = true **
    BeaconMonitor: listener removed
    sending message to waiting queue (CallSubDelayed - BeaconMonitor_ScanComplete)
    sending message to waiting queue (CallSubDelayed - BeaconMonitor_ScanIdle)
    sending message to waiting queue (ibeaconlistener_searchstate)
    sending message to waiting queue (ibeaconlistener_searchstate)
    ** Activity (main) Create, isFirst = false **
    running waiting messages (4)
    Error occurred on line: 48 (BeaconMonitor)
    java.lang.NullPointerException: Attempt to invoke virtual method 'uk.co.martinpearman.b4a.easibeacon.IBeacon[] uk.co.martinpearman.b4a.easibeacon.IBeaconProtocol.GetIBeaconsByProximity()' on a null object reference
    at b4a.easibeaconsdemo.beaconmonitor._getibeaconsbyproximity(beaconmonitor.java:216)
    at b4a.easibeaconsdemo.main._beaconmonitor_scancomplete(main.java:535)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:302)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.keywords.Common$5$1.run(Common.java:966)
    at anywheresoftware.b4a.BA.setActivityPaused(BA.java:404)
    at b4a.easibeaconsdemo.main.afterFirstLayout(main.java:104)
    at b4a.easibeaconsdemo.main.access$100(main.java:17)
    at b4a.easibeaconsdemo.main$WaitForLayout.run(main.java:78)
    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:5832)
    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)
    Installing file.
    PackageAdded: package:b4a.easibeaconsdemo
    ** Activity (main) Create, isFirst = true **
    ** Activity (main) Resume **
    BeaconMonitor: listener added
    BeaconMonitor: ScanStart
    ** Activity (main) Pause, UserClosed = false **
    BeaconMonitor: listener removed
    ** Activity (main) Resume **
    BeaconMonitor: listener added
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanIdle
    BeaconMonitor: ScanIdle_Tick
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanIdle
    BeaconMonitor: ScanIdle_Tick
    BeaconMonitor: ScanStart
    BeaconMonitor: ScanComplete
    BeaconMonitor: ScanIdle
    ** Activity (main) Pause, UserClosed = false **
    BeaconMonitor: listener removed
     
  9. warwound

    warwound Expert Licensed User

    Looks like you're not initializing your IBeaconProtocol object.
     
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