Android Tutorial [B4x]Data exchange (B4x, php, servers, .net and others)

KMatle

Expert
Licensed User
After some years I have developed several apps to communicate with other apps, servers and platforms. My goal was to have ONE standard solution without additional propriatary solutions which work only on platform a but not on b. So I've ended up with lists and maps converted from/to JSON strings.

Why to a string? Because it's simple to handle. Strings can be converted very easy to bytes if you need it encrypted. The result (because encryption workds with bytes) can be converted to a string again (Base64) and you're good.

Why lists and maps? Because you can have complex and flexible structures which then can be handled as a string which can easily exchanged between platforms. Lists and maps are just arrays which can be "understood" by all programs. Same for Base64 and JSON.

Example:

B4X:
Dim Parms As Map
    Parms.Initialize
    Parms.put("uname", "Smith")
    Parms.put("upw", "12345")
    Parms.put("api-key", "9999")

Dim FileBuffer(0) As Byte 
FileBuffer=Bit.InputStreamToBytes(File.OpenInput(Dir, FileName))
Dim B64String As String = su.EncodeBase64(FileBuffer)
Parms.put("myfile", B64String)

    Dim Alist As List
    Alist.Initialize
    Alist.Add(Parms)
        
    Dim JG As JSONGenerator
    JG.Initialize2(Alist)
What do we have here? We define a list and a map. The map is filled with some data and even a file converted to a base64 string. As you see we've combined complex data (a file is complex) but as you see it is very simple.

Now we can decide what we need: Use it is, convert it to a Base64 string (to keep compatibility between platforms) or even convert it to bytes (to send it via asyncstreams or other)

With

B4X:
JG.ToString.GetBytes("UTF8")
you get bytes. With encryption (here I send it via asyncstreams)

B4X:
...
SendData(JG.ToString.GetBytes("UTF8"))
...

Public Sub SendData (data() As Byte)
    If connected Then
        astream.Write(EncryptBytes(data,"pw"))
    End If
End Sub
Via OkHttpUtils job (no encryption)

B4X:
Dim JSONGenerator As JSONGenerator
    JSONGenerator.Initialize2(JSONList)
   
    Dim JSONstring As String
    JSONstring = JSONGenerator.ToString

Dim MyJob As HttpJob
    MyJob.Initialize("GetItems", Me)
    MyJob.PostString(Servername & ScriptPath, JSONstring)
I you need to encrypt, convert the bytes to a Base64 string and send it.

Summary

- we have ONE string
- all platforms can handle JSON and Base64
- a list with maps is just an array with an array
- maps can be added to the list without changing anything else in the code

In php:

B4X:
$json = file_get_contents("php://input"); 'get the string we've sent (poststring method)

    $thelist = array(); 'define an array = our list
    $onemap = array(); 'define an array = out map
    $thelist=json_decode($json, true); = our list assuming you've did a Base64 encoding before you send

    $themap=$thelist[0]; ' get the first map. We only send one but you can add several maps to the list (e.g. to insert 10 items in a db)
In vb.net (just an example to send a list with a map, see the .net docs how to use poststring)

B4X:
OwnPubKey64StringExport = Convert.ToBase64String(OwnPubKeyBytes)
Dim serializer As New JavaScriptSerializer()
        Dim di As New Dictionary(Of String, String)
        di.Add("Action", "EncTest")
        di.Add("MyUsernummer", "777777")
        di.Add("MyUserMail", "nothing")
        di.Add("MyUserPW", "nothing")
        di.Add("PK", OwnPubKey64StringExport)
        serializedResult = "[" & serializer.Serialize(di) & "]" 'just a trick: [ = start of a list

        phpResult = myWebClient.DownloadString(Servername & Serverpath & "?Message=" & serializedResult)
Libs needed:

StringUtils
OkHttpUtils
JSON
 
Top