Android Question HttpJob cannot handle application/json response

gglaz

Member
Licensed User
Longtime User
Hello,

I was looking at the forum for an answer but failed to find a solution.

What I am intending to do is to send a JSON request o my API. Task seems to be easy and the code is short:

B4X:
Dim JSONg As JSONGenerator
JSONg.Initialize(postImageMap)

Dim http As HttpJob
http.Initialize("http", Me)
http.Username = "someusername"
http.Password = "averysecurepassword"
http.PostString("http://1.1.1.1/api.php/image", JSONg.ToString)
http.GetRequest.SetContentType("application/json")

postImageMap is just a map with some values. JSON string looks as follows:
B4X:
{"Image":"Image","QRCode":"QRCode","Vorname":"Vorname","Gebdate":"30-01-1987","Strasse":"Strasse","ScanDate":"","SaveDate":"","PLZ":"13407","Standort_id":"0","ProgrammVersion":"","Device":{"Mac":"","DeviceName":"hyyy","DeviceKey":"yyyyu","DeviceType":""}}

This code runs in a service, trying to communicate with the API every now and then.

How can I debug it? JobDone is not fired so Log calls are not doing anything. I don't receive any error message. No idea how to fix it because I get no feedback. I tried the same JSON string with a REST client and it worked. It seems that http is NOT sending the request. Did I miss some kind of "http.fire" function or something?
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

gglaz

Member
Licensed User
Longtime User
Thank you for your answer, DonManfred.

Nah, I just changed it from real IP to localhost. I will edit it to avoid more confusion.
 
Upvote 0

gglaz

Member
Licensed User
Longtime User
Thank you Erel for the answer. I will post it with pleasure

This is the whole body of a Service_Start function:
B4X:
If File.Exists(File.DirInternal, "status.txt") == True Then
        Dim jsonString As String
        Dim JSON As JSONParser
        Dim mapEntries As Map
    
        'Load JSON to a Map
        jsonString = File.ReadString(File.DirInternal, "status.txt")
        JSON.Initialize(jsonString)
        mapEntries.Initialize
        mapEntries = JSON.NextObject
    
        'Iterate
        Dim listEntries As List
        listEntries.Initialize
        listEntries = mapEntries.Get("entries")
        For i = 0 To listEntries.Size-1
            Dim entry As Map
            entry.Initialize
            entry = listEntries.Get(i)
        
            'Process only those not ready yet
            If entry.Get("status") == "pending" Then
                'Prepare data to post.
                Dim deviceMap As Map
                deviceMap.Initialize
                deviceMap.Put("Mac", "")
                deviceMap.Put("DeviceName", Settings.DeviceId)
                deviceMap.Put("DeviceKey", Settings.DevicePin)
                deviceMap.Put("DeviceType","")
                Dim postImageMap As Map
                postImageMap.Initialize

                'Dim Base64Con As Base64Image
                'Base64Con.Initialize
                'Dim ImageB64 As String
                'ImageB64 = Base64Con.EncodeFromImage(File.DirRootExternal, entry.Get("file_name"))
            
                postImageMap.Put("Image", "Image")
                postImageMap.Put("QRCode", "QRCode")
                postImageMap.Put("Vorname", "Vorname")
                postImageMap.Put("Gebdate", "30-01-1987")
                postImageMap.Put("Strasse", "Strasse")
                postImageMap.Put("ScanDate", "")
                postImageMap.Put("SaveDate", "")
                postImageMap.Put("PLZ", "13407")
                postImageMap.Put("Standort_id", Settings.Place)
                postImageMap.Put("ProgrammVersion", "")
                postImageMap.Put("Device", deviceMap)

                Dim JSONg As JSONGenerator
                JSONg.Initialize(postImageMap)

                Log(JSONg.ToString)

                Dim http As HttpJob
                http.Initialize("http", Me)
                http.Username = "username"
                http.Password = "password"
                http.PostString("http://1.1.1.1/api.php/image", JSONg.ToString)
                http.GetRequest.SetContentType("application/json")
            End If
        Next
    End If


It might be important: the server responses with application/json content type. May it be that I have to change response type HttpJob expects?
 
Last edited:
Upvote 0

gglaz

Member
Licensed User
Longtime User
There was a mistake in the copied Code (I have already fixed that). I am actively playing around to find a solution.

I initilize job to fire JobDone event in the "Me" Activity.

B4X:
http.Initialize("http", Me)

So inside the service there is this fucntion:
B4X:
Sub JobDone (Job As HttpJob)
    Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
    Job.Release
End Sub
 
Upvote 0

gglaz

Member
Licensed User
Longtime User
Thank you for your time. Here is the full code of the service:
B4X:
#Region  Service Attributes 
    #StartAtBoot: True
#End Region

Sub Process_Globals
    Dim TimerService As Timer
End Sub

Sub Service_Create
    TimerService.Initialize("TimerService", 5000)
    TimerService.Enabled = True
End Sub

Sub Service_Start (StartingIntent As Intent)
    Post
End Sub

Sub Service_Destroy
End Sub

Sub TimerService_Tick
    StartServiceAt("", DateTime.Now, True)
End Sub

'POSTING IN THE BG
Sub Post
    'Read file
    If File.Exists(File.DirInternal, "status.txt") == True Then
        Dim jsonString As String
        Dim JSON As JSONParser
        Dim mapEntries As Map
       
        'Load JSON to a Map
        jsonString = File.ReadString(File.DirInternal, "status.txt")
        JSON.Initialize(jsonString)
        mapEntries.Initialize
        mapEntries = JSON.NextObject
       
        'Iterate
        Dim listEntries As List
        listEntries.Initialize
        listEntries = mapEntries.Get("entries")   
        For i = 0 To listEntries.Size-1
            Dim entry As Map
            entry.Initialize
            entry = listEntries.Get(i)
           
            'Process only those not ready yet
            If entry.Get("status") == "pending" Then
                'Prepare data to post.
                Dim deviceMap As Map
                deviceMap.Initialize
                deviceMap.Put("Mac", "")
                deviceMap.Put("DeviceName", Settings.DeviceId)
                deviceMap.Put("DeviceKey", Settings.DevicePin)
                deviceMap.Put("DeviceType","")
                Dim postImageMap As Map
                postImageMap.Initialize

                'Dim Base64Con As Base64Image
                'Base64Con.Initialize
                'Dim ImageB64 As String
                'ImageB64 = Base64Con.EncodeFromImage(File.DirRootExternal, entry.Get("file_name"))
               
                postImageMap.Put("Image", "Image") 'EncodeAESString(ImageB64))
                postImageMap.Put("QRCode", "QRCode")
                postImageMap.Put("Vorname", "Vorname")
                postImageMap.Put("Gebdate", "30-01-1987")
                postImageMap.Put("Strasse", "Strasse") 
                postImageMap.Put("ScanDate", "")
                postImageMap.Put("SaveDate", "")
                postImageMap.Put("PLZ", "13407")
                postImageMap.Put("Standort_id", Settings.Place)
                postImageMap.Put("ProgrammVersion", "")
                postImageMap.Put("Device", deviceMap)

                Dim JSONg As JSONGenerator
                JSONg.Initialize(postImageMap)

                Log(JSONg.ToString)

                Dim http As HttpJob
                http.Initialize("http", Me)
                http.Username = "Username"
                http.Password = "Password"
                http.PostString("http://1.1.1.1/api.php/image", JSONg.ToString)
                http.GetRequest.SetContentType("application/json")
            End If
        Next
    End If
End Sub

Sub JobDone (Job As HttpJob)
    Log("JobName = " & Job.JobName & ", Success = " & Job.Success)

    Job.Release
End Sub

I start the service in the main activity. Any help will be appreciated.
 
Upvote 0

gglaz

Member
Licensed User
Longtime User
Thank you for your hint. I moved the code and it looks much nicer. But JobDone is still not fired.

Looks like it is the API problem. Response is JSON string like i.e.

B4X:
{
  "status": "ok",
  "id": "744"
}

With content-type application/json.

Do I need to prepare HttpJob object for such a response? I am not sure where to look for mistakes. No Idea how to debug this thing.

Additionally, http.Success is always false. Is it by default or is it possible that the job failed just not fired JobDone?


EDIT:

In the logger i can see that the http service is created and started

** Service (httputils2service) Create **
** Service (httputils2service) Start **

Can I somehow get inside that service? Like put some debug lines in it? Somehow, somewhere.

When is the JobDone fired? Under what circumstances? What does the response must look like? I noticed that JobDone is fired when I use wrong IP address. It means that Job is just NOT FINISHED. It looks like it was waiting for a specific event to happen. My API sends Code 200. Somehow it is not enough.
 
Last edited:
Upvote 0

gglaz

Member
Licensed User
Longtime User
Thank you for your time, Erel. I have to do a different task next days, but I will be back and provide an answer to this problem.
 
Upvote 0
Top