Android Question Httjob "failed to connect" in background service

GraemeW

Member
Licensed User
I'm writing an app to count users passing through specified areas. "Geofence" feature isn't reliable because it's a rural area with few phone towers, so I'm using periodic calls to the LocationMonitor service which uses a fusedlocationprovider object.

New locations from LocationMonitor are sent to a sub in Starter; if a location is within a radius distance of a lat/lon point then a htttjob in another Starter sub sends an Insert SQL request to the remote database.

This works perfectly when the app is in the foreground but when it's in background or closed the httpjob gets the error "java.net.ConnectException: Failed to connect to " (sqlserver)

I've used httjobs in background services before without problems, and I can't find anything related here - has some security setting changed in updates that I've missed? (using https instead of http had no effect)

B4A version 9.30, targetSdkversion=28, testing on Samsung S9
 

GraemeW

Member
Licensed User
More clues:

1) http works with app in background if app is connected to internet by office wifi - does not work when wifi off and connection is by mobile data (4G)

2) http works with 4G connection (wifi off) if app is in foreground

So http connection problem occurs when app in background and connected to internet by mobile data - which is most of the time for intended users...
 
Upvote 0

GraemeW

Member
Licensed User
another clue from the detailed log:

Caused by: android.system.ErrnoException: isConnected failed: ECONNREFUSED (Connection refused)
at libcore.io.IoBridge.isConnected(IoBridge.java:267)

very odd....
 
Upvote 0

GraemeW

Member
Licensed User
Thank you Erel - unfortunately there was no change using the Starter subs below

B4X:
Sub LocationChanged(Location1 As Location)

    StopService(LocationMonitor)
    
    Log("LocationChanged at " & DateTime.Time(DateTime.Now))
    locationUser = Location1

    Check_OnIsland
    Check_Geofences
    
    TestUpload(locationUser)
End Sub

Sub TestUpload(x As Location)

    Dim lock As PhoneWakeState
    lock.PartialLock
    
    Dim s As String
    s = "Insert Into geofences (Device_ID, Latitude, Longitude, Geofence_ID, Time_In) Values ('" & appSetting.Get("PhoneID") & "'," & x.Latitude & "," & x.Longitude & ", 'Test', " & DateTime.Now & ")"

    Dim job As HttpJob
    job.Initialize("", Me)
    
    Dim count As Int = 0
    
    Do While (job.Success = False) And (count < 5)

        count = count + 1
        
        Sleep(2000)
        
        job.PostString(sqlServer,s)
        Wait For (job) JobDone(job As HttpJob)
        
        If job.Success = False Then
            Log("Error" & count & " = " & job.ErrorMessage)
        End If
            
    Loop
            
    job.Release

    lock.ReleasePartialLock
    
End Sub
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
Upvote 0

GraemeW

Member
Licensed User
No solution yet but another clue: my original code worked perfectly this morning on my wife's identical phone (S9) but with a different network operator..

Unfortunately, Erel's further suggestion didn't work on my phone using the code below. Changing targetSdkversion from 28 to 23 also didn't work but I'm looking further into network optimizations for background services... or whether something is wrong on the php/sql server

B4X:
Sub TestUpload(x As Location)
   
    Dim lock As PhoneWakeState
    lock.PartialLock
   
    Dim s As String
    s = "Insert Into geofences (Device_ID, Latitude, Longitude, Geofence_ID, Time_In) Values ('" & appSetting.Get("PhoneID") & "'," & x.Latitude & "," & x.Longitude & ", 'Test', " & DateTime.Now & ")"

    For i = 1 To 5
       
        Dim job As HttpJob
        job.Initialize("", Me)
        job.GetRequest.Timeout = 60000
        job.PostString(sqlServer,s)
        Wait For (job) JobDone(job As HttpJob)
        If job.Success Then
            Log("httpjob success at attempt " & i)
            Exit
        Else
            Log("Error at attempt " & i & " = " & job.ErrorMessage)
        End If          
        job.Release
       
        Sleep(2000)
       
    Next
   
    lock.ReleasePartialLock
   
End Sub
 
Last edited:
Upvote 0

GraemeW

Member
Licensed User
Attached is a small test app which simulates my http connection problem. On start it loads a service "Upload" which calls a Starter sub to insert test data into my sql database. Upload is called again every 90 seconds.

1) app in foreground with phone using wifi or mobile data - https works
2) app in background with phone using wifi - https works
3) app in background with phone using mobile data - https fails with conn error

If anyone has time could you please check if you can replicate the problem - and perhaps suggest a solution? Having searched everywhere for the last 5 days I see others have had similar connection issues over the years but the solution has usually been to use https rather than http. That is not the problem here...
 

Attachments

  • conntest.zip
    10.1 KB · Views: 172
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
There are several mistakes in this code.

1. StartServiceAt shouldn't be used in intervals less than 15 minutes.
2. You are stopping the foreground mode too quickly.
3. You are not acquiring a partial lock.

It would have been better to try to keep the service running all the same in foreground mode. See this example: Background location tracking
 
Upvote 0

Xicu

Active Member
Licensed User
Longtime User
There are several mistakes in this code.
1. StartServiceAt shouldn't be used in intervals less than 15 minutes.
What happens if lower intervals are used?
Will it simply be ignored by the android system?
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

GraemeW

Member
Licensed User
Many thanks Erel - after sleeping on it I got the test app working with https successful in all cases with your suggestions and the background tracking example.

Now to translate that to my main app - and rather than calling and stopping the LocationMonitor service every 2 minutes (or 24 hours if users are far away) I'll adjust the interval in its LocationRequest - or only start LocationMonitor when user is inside a very large Geofence..
 
Last edited:
Upvote 0
Top