Android Question "auto refresh" Android tablet

AKJammer

Active Member
Licensed User
Hey All,
I'm working on a project that requires the tablet to refresh the screen without user input if data changes. How I've implemented it is a field in the database that, if set to '1', will trigger a call to the refresh button that is available to the user. If RefreshBtn is pressed, the first thing it does is goes to the database and sets the flag to '0'. This is all handled within a check refresh subroutine that polls the database every variable (currently 10) seconds. The problem I have is that it works just fine when I'm debugging and have the tablet connected via bridge, but once I put the code in Release mode and copy it over to another tablet, the refresh never happens. The database flag stays set to '1'. If I do a manual refresh, the flag is set to '0'.

Any insights would be helpful.

Here's my subroutine.
B4X:
Sub refresh_check
Log(refreshtimer * 1000)   ' currently set to 10 (seconds)
    Do While 1 = 1
        Log("tick")
        Sleep(refreshtimer * 1000) '60000 = 1 min
        

            Dim req As DBRequestManager = CreateRequest
            Dim cmd As DBCommand = CreateCommand("check_refresh", Array(prepid, jdgnumber))
            Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
            If j.Success Then
                req.HandleJobAsync(j, "req")
                Wait For (req) req_Result(res As DBResult)
                Dim row() As Object = res.Rows.Get(0)
                
                If row(0) = 1 Then
                 Log("do refresh")
                 Refresh_Click    
                End If
            End If 
            j.release
                    
    Loop
End Sub
 

AKJammer

Active Member
Licensed User
Didn't know there was such an animal. Will take a look.

A separate routine would do the exact same thing as a manual refresh, so no need to duplicate code.

So other than not using a built in object, any idea why it only works in debug?
 
Upvote 0

AKJammer

Active Member
Licensed User
Ok, I found the timer object, didn't know we had one. Modified the code to use it, but still doesn't work in Release mode.

Code:
Sub Process_Globals
    Public RefreshTimer As Timer

Sub Activity_Create
        RefreshTimer.Initialize("RefreshTimer", timerInterval * 1000) 
        RefreshTimer.Enabled = True


Private Sub RefreshTimer_Tick
        Log("tick")
  
        If prepid > 0 And jdgnumber >= 0 Then   'prepid = 78, jdgnumber = 4

      
            Dim req As DBRequestManager = CreateRequest
            Dim cmd As DBCommand = CreateCommand("check_refresh", Array(prepid, jdgnumber))
            Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
            If j.Success Then
                req.HandleJobAsync(j, "req")
                Wait For (req) req_Result(res As DBResult)
                Dim row() As Object = res.Rows.Get(0)
                
                If row(0) = 1 Then
                 Log("do refresh")
                 Refresh_Click    
                End If
            End If 
            j.release

      End If

End Sub
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
@AKJammer said: The problem I have is that it works just fine when I'm debugging and have the tablet connected via bridge, but once I put the code in Release mode and copy it over to another tablet, the refresh never happens.
You did two things.
Does it work on the tablet that you used for development in release mode?
If yes, then the second tablet has some setting that is causing the problem.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I see two things I don't like:

1 - the routine calls itself (and this is one more reason not to directly call an event routine of a view)

2 - It executes that call without releasing the job.
 
Upvote 0

Alex_197

Well-Known Member
Licensed User
Longtime User
You can use a push instead of pull.
If the information on the server has changed - your web page or the app on the server will push the information via the Firebase notification to the mobile device.
On the mobile device you can use an event fm_MessageArrived, read the info and update the screen, database, etc... in your app.
 
Upvote 0

AKJammer

Active Member
Licensed User
You did two things.
Does it work on the tablet that you used for development in release mode?
If yes, then the second tablet has some setting that is causing the problem.
Hmmm, good check. When I run it in release mode with the tablet attached to bridge, it doesn't work there either.

Then I noticed that when in Debug mode, it only worked when I had a breakpoint inside the function where the log("tick") is located. I'm getting the 'tick' logged every 10 secs, but it's not going to Refesh_Click unless I'm stepping through it.
 
Upvote 0

AKJammer

Active Member
Licensed User
I see two things I don't like:

1 - the routine calls itself (and this is one more reason not to directly call an event routine of a view)

2 - It executes that call without releasing the job.
Do you have a good link to explain best practices for using the timer object? What I have coded is pretty much a copy of what I found already. I didn't see where a release would happen since the timer would be operating the entire lifespan of the app.

Thanks.
 
Upvote 0

AKJammer

Active Member
Licensed User

Ok, the debug mode issue was because of the naming of the object and the callback the same as LucasM mentioned. So it's working again in Debug, but still not in Release, even attached to Bridge.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
I was referring to j.release, which is not executed when the routine calls itself from within.
This isn't necessarily the problem at all, it's just something I noticed "on the fly".
 
Upvote 0

AKJammer

Active Member
Licensed User
I was referring to j.release, which is not executed when the routine calls itself from within.
This isn't necessarily the problem at all, it's just something I noticed "on the fly".
Ah, ok, Not really part of this issue, but why wouldn't j.release get called? It's right after the IF block to see if successful.

Actually, I went ahead and added some more log entries, so this is interesting. This only happens in Release mode

B4X:
Private Sub Runtimer_Tick
        Log("tick")
        Sleep (500)
        If prepid > 0 And jdgnumber >= 0 Then

            Dim req As DBRequestManager = CreateRequest
            Log("...1")
        Dim cmd As DBCommand = CreateCommand("check_refresh", Array(prepid, jdgnumber))
        Log("...2")
        Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
        Log("...3")

            If j.Success Then
            Log("...4")

                req.HandleJobAsync(j, "req")
            Log("...5")

                Wait For (req) req_Result(res As DBResult)
            Log("...6")

                Dim row() As Object = res.Rows.Get(0)
            Log("...7")
             Log (row(0))
                If row(0) = 1 Then
                 Log("do refresh")
                 Refresh_Click    
                Log("...8")

                End If
            Log("...9")

            End If 
        Log("...10")

            j.release
            Log("end if")
            
            
            
        End If

End Sub

Here's the log. It doesn't do the refresh, but the returned value from the database is 1 !?!?!? Line 25's IF statement should be true.

 
Upvote 0

AKJammer

Active Member
Licensed User
Create J
Do some queries
if queries are good then
do some more
end if
Release J


If success doesn't effect the release of J, as can be seen by the log trace. Am I missing something obvious?

Anyone know why 1 = 1 wouldn't come back as True?
 
Upvote 0

bdunkleysmith

Active Member
Licensed User
Longtime User
I really know nothing about this, but using my "trial and error" method of working with B4X I'd try:

B4X:
If row(0) = "1" Then

or

B4X:
If 1 = row(0) Then
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User

Your code:
B4X:
            Dim req As DBRequestManager = CreateRequest
            Dim cmd As DBCommand = CreateCommand("check_refresh", Array(prepid, jdgnumber))
            Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
            If j.Success Then
                req.HandleJobAsync(j, "req")
                Wait For (req) req_Result(res As DBResult)
                Dim row() As Object = res.Rows.Get(0)
                
                If row(0) = 1 Then
                 Log("do refresh")
                 Refresh_Click   ' <--- Here 
                End If
            End If
            j.release

Calling Refresh_Click you leave the running routine, call it again without releasing the job (j.release is not executed).
Again, this, while incorrect, probably has nothing to do with the problem.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
This is something I don't understand well and it seems rather convoluted to me:
B4X:
Sub refresh_check
Log(refreshtimer * 1000)   ' currently set to 10 (seconds)
    Do While 1 = 1
        Log("tick")
        Sleep(refreshtimer * 1000) '60000 = 1 min
You want to call that Sub every 10 seconds but then inside the loop you make it take a 60 second pause; why?
Note that Sleep returns the flow to the caller.
 
Upvote 0

PerryHart

New Member
You can try these steps:

Check database permissions.

Check network connectivity and configure automatic refresh.

Check the log file to see if there are any error messages.

If you need further assistance, we apologize for any inconvenience and please reach out for help.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…