Android Tutorial Android JSON tutorial

Status
Not open for further replies.
JSON format is a a format similar to XML but usually it is shorter and easier to parse.
Many web services now work with JSON. JSON official site: JSON

Using the new JSON library, you can parse and generate JSON strings easily.

As an example we will parse a the following JSON string:
B4X:
{"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}
This example was taken from json.org/examples.
Curl brackets represent an object and square brackets represent an array.
Objects hold key/value pairs and arrays hold list of elements. Commas separate between elements.

In this example, the top level value is an object. This object contains a single object with the key "menu".
The value of this object is another object that holds several elements.
We will get the "menuitem" element, which holds an array of objects, and print the values of the "value" element.

After parsing the string, JSON objects are converted to Maps and JSON arrays are converted to Lists.
We will read this string from a file added by the files manager (Files tab).
B4X:
    Dim JSON As JSONParser
    Dim Map1 As Map
    JSON.Initialize(File.ReadString(File.DirAssets, "example.json"))
    Map1 = JSON.NextObject
    Dim m As Map 'helper map for navigating
    Dim MenuItems As List
    m = Map1.Get("menu")
    m = m.Get("popup")
    MenuItems = m.Get("menuitem")
    For i = 0 To MenuItems.Size - 1
        m = MenuItems.Get(i)
        Log(m.Get("value"))
    Next
JSON.NextObject parses the string and returns a Map with the parsed data. This method should be called when the top level value is an object (which is usually the case).
Now we will work with Map1 to get the required values.
We declare an additional Map with the name 'm'.
B4X:
m = Map1.Get("menu")
The object that maps to "menu" is assigned to m.
B4X:
m = m.Get("popup")
The object that maps to "popup" is now assigned to m.
B4X:
MenuItems = m.Get("menuitem")
The array assigned to "menuitem" is assigned to the MenuItems list.
We will iterate over the items (which are maps in this case) and print the values stored in the elements with "value" key.
B4X:
    For i = 0 To MenuItems.Size - 1
        m = MenuItems.Get(i)
        Log(m.Get("value"))
    Next
The output in the LogCat is:
New
Open
Close

Generating JSON strings is done in a similar way. We create a Map or a List that holds the values and then using JSONGenerator we convert it to a JSON string:
B4X:
    Dim Data As List
    Data.Initialize
    Data.Add(1)
    Data.Add(2)
    Data.Add(3)
    Data.Add(Map1) 'add the previous map loaded from the file.
    Dim JSONGenerator As JSONGenerator
    JSONGenerator.Initialize2(Data)
    Msgbox(JSONGenerator.ToPrettyString(2), "")
JSONGenerator can be initialized with a map or a list.
Converting the data to a JSON string is done by calling ToString or ToPrettyString. ToPrettyString adds indentation and is easier to read and debug.

json_1.png


A tool to help you with working with JSON strings: https://b4x.com:51041/json/index.html
 

Attachments

  • JSONExample.zip
    5.2 KB · Views: 6,089
Last edited:

ivanomonti

Expert
Licensed User
Longtime User
Json record

B4X:
[{"a01":"Via dell'Industria  Solaro  MI,  Italia","a02":"Desidero fiore","a03":"user-male.png","a04":"45.622287822509854","a05":"9.107269731567708","a06":"1.4071125984191895","a07":"06-05-2014","a08":"15:52:50","a09":"test","r1":"0"},{"a01":"Via dell'Industria  Solaro  MI,  Italia","a02":"Desidero auto","a03":"user-female.png","a04":"45.62198194001763","a05":"9.107868433652834","a06":"0.9736074805259705","a07":"06-05-2014","a08":"21:59:13","a09":"test","r1":"0"}]

Code

B4X:
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
    Dim s As String
    s = Response.GetString("UTF8")
  
    Log(s)
  
    Dim JSON As JSONParser
    JSON.Initialize(s)
  
    Try
        Dim Map1 As Map
        Map1 = JSON.NextObject ' error line
        ListView1.AddSingleLine(Map1.Get("display_name"))
    Catch
        Msgbox("Error",Response.GetString("UTF8"))
    End Try
    Response.Release
End Sub

Error parse


B4X:
Error occurred on line: 92 (main)

java.lang.RuntimeException: JSON Object expected.

at anywheresoftware.b4a.objects.collections.JSONParser.NextObject(JSONParser.java:47)

at java.lang.reflect.Method.invokeNative(Native Method)

at java.lang.reflect.Method.invoke(Method.java:525)

at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:485)

at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:229)

at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:174)

at java.lang.reflect.Method.invokeNative(Native Method)

at java.lang.reflect.Method.invoke(Method.java:525)

at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)

at anywheresoftware.b4a.BA$3.run(BA.java:318)

at android.os.Handler.handleCallback(Handler.java:730)

at android.os.Handler.dispatchMessage(Handler.java:92)

at android.os.Looper.loop(Looper.java:137)

at android.app.ActivityThread.main(ActivityThread.java:5493)

at java.lang.reflect.Method.invokeNative(Native Method)

at java.lang.reflect.Method.invoke(Method.java:525)

at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)

at dalvik.system.NativeStart.main(Native Method)

!!! :-(
 

DonManfred

Expert
Licensed User
Longtime User
B4X:
Dim parser As JSONParser
parser.Initialize(s)
Dim root As List = parser.NextArray
For Each colroot As Map In root
   Dim a01 As String = colroot.Get("a01")
   Dim a02 As String = colroot.Get("a02")
   Dim a03 As String = colroot.Get("a03")
   Dim a04 As String = colroot.Get("a04")
   Dim a05 As String = colroot.Get("a05")
   Dim a06 As String = colroot.Get("a06")
   Dim a07 As String = colroot.Get("a07")
   Dim a08 As String = colroot.Get("a08")
   Dim a09 As String = colroot.Get("a09")
   Dim r1 As String = colroot.Get("r1")
Next

BTW: There is no "display_name" in the json

PS: You can use this to get correct code for json-parse
 

little3399

Active Member
Licensed User
Longtime User
Hi ,Erel

I found a bug in Json lib , when there are member of json object it's value was null will be

cause a error "....
Error occurred on line: 238 (main)
org.json.JSONException: Expected literal value at character 109 of {ShopName=广州市越秀区中山五路219号(近人民公园南广场)动漫星城, Status=0, VisitDate=2013-5-31, RpjName=演示项目13M5, Vid=215900, Address=} " ... in this example the value of the "Address" is null

Is this a bug of JSON LIB ? tks!
 

little3399

Active Member
Licensed User
Longtime User
Not sure ,here is our original json data in attachment file (1.zip)
 

Attachments

  • 1.zip
    456 bytes · Views: 665

little3399

Active Member
Licensed User
Longtime User
Oh,Erel,I put a wrong 1.json file , and you can try this , such as let Address="" or Address=" ", and usd jp.nextobject .... , I had update the 1.zip file

Tks!

Dim JSON As JSONParser
Dim Map1 As Map

JSON.Initialize(File.ReadString(File.DirAssets, "1.json"))
Log("JSON="&JSON)
Dim List1 As List
List1.Initialize
List1=JSON.NextArray
Log(List1)
Map1.Initialize
For i=0 To List1.Size-1
Log(List1.Get(i))
JSON.Initialize(List1.Get(i))
Map1=JSON.NextObject
Log(Map1.Get("Vid"))
Log(Map1.Get("ShopName"))
Log(Map1.Get("RpjName"))
Log(Map1.Get("VisitDate"))
Log(Map1.Get("Address"))
Log(Map1.Get("Status"))

Next
 

Attachments

  • 1.zip
    460 bytes · Views: 596

little3399

Active Member
Licensed User
Longtime User
Hi, Erel
Your mean the Json method such as json.NextArray, NextObject ... only be call once ,if they call again will be cause some error ?
 

ivanomonti

Expert
Licensed User
Longtime User
error parse nextArray


B4X:
Error occurred on line: 134 (main)
java.lang.RuntimeException: JSON Array expected.
   at anywheresoftware.b4a.objects.collections.JSONParser.NextArray(JSONParser.java:62)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   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.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
   at anywheresoftware.b4a.BA$3.run(BA.java:319)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:136)
   at android.app.ActivityThread.main(ActivityThread.java:5103)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
   at dalvik.system.NativeStart.main(Native Method)

B4X:
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
   Try
     If Response <> Null Then
       Dim s As String
       s = Response.GetString("UTF8")
   
       Dim parser As JSONParser
       parser.Initialize(s)
       Dim root As List
       root.Initialize
       root = parser.NextArray  ' < line error >

       For Each colroot As Map In root
        Module_setting.address = colroot.Get("prv")
       Next
       
       Response.Release
     End If
   Catch
     End Try
End Sub

JSon result

B4X:
{
  "results" : [
  {
  "address_components" : [
  {
  "long_name" : "Strada Provinciale 25",
  "short_name" : "SP25",
  "types" : [ "route" ]
  },
  {
  "long_name" : "Boffalora d'Adda",
  "short_name" : "Boffalora d'Adda",
  "types" : [ "administrative_area_level_3", "political" ]
  },
  {
  "long_name" : "Lodi",
  "short_name" : "LO",
  "types" : [ "administrative_area_level_2", "political" ]
  },
  {
  "long_name" : "Lombardy",
  "short_name" : "Lombardy",
  ......
 

little3399

Active Member
Licensed User
Longtime User
Your must using JSON.NextObject to handel your json data, and not Json.nextarrary ...
 

ivanomonti

Expert
Licensed User
Longtime User
B4X:
Private Sub jsonParseCategory(s As String)
   Try
     Log(s)
       Dim JSON As JSONParser
     JSON.Initialize(s)
     ListCategory = JSON.NextArray
     ToastMessageShow("Updated category list", True)
   Catch
     ToastMessageShow("Error parse json data", True)
     End Try
End Sub

B4X:
start,-a,android.intent.action.MAIN,-n,b4a.example/.main,-f,0x20000000
(Intent) Intent { act=android.intent.action.MAIN flg=0x20000000 cmp=b4a.example/.main }
no extras
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
Query: category[{"Category":"Animal","SubCategory":"Dog Sitter"},{"Category":"Animal","SubCategory":"Cat Sitter"},{"Category":"Animal","SubCategory":"Veterinary"},{"Category":"Animal","SubCategory":"Other"},{"Category":"Work","SubCategory":"Painter"},{"Category":"Work","SubCategory":"Mason"},{"Category":"Work","SubCategory":"Elettrical"},{"Category":"Work","SubCategory":"Hydraulic"},{"Category":"Work","SubCategory":"Garden"},{"Category":"Work","SubCategory":"Other"},{"Category":"Assistance","SubCategory":"Garegivers"},{"Category":"Assistance","SubCategory":"Nurse"},{"Category":"Assistance","SubCategory":"General practitioner"},{"Category":"Assistance","SubCategory":"Dentist"},{"Category":"Assistance","SubCategory":"Gynecologist"},{"Category":"Assistance","SubCategory":"Physiotherapist"},{"Category":"Advice","SubCategory":"Mediator"},{"Category":"Advice","SubCategory":"Criminal Lawyer"},{"Category":"Advice","SubCategory":"Civil lawyer"},{"Category":"Advice","SubCategory":"Noary"},{"Category":"Advice","SubCategory":"Accountant"},{"Category":"Advice","SubCategory":"Business Consultant"},{"Category":"Personal Care","SubCategory":"Hairdresser"},{"Category":"Personal Care","SubCategory":"Beautician"},{"Category":"Personal Care","SubCategory":"Personal Trainer"},{"Category":"Personal Care","SubCategory":"Masseur"},{"Category":"Personal Care","SubCategory":"masseuse"},{"Category":"Animal","SubCategory":"All"},{"Category":"Work","SubCategory":"All"},{"Category":"Assistance","SubCategory":"All"},{"Category":"Advice","SubCategory":"All"},{"Category":"Personal Care","SubCategory":"All"}]
Error occurred on line: 80 (main)
java.lang.RuntimeException: JSON Array expected.
    at anywheresoftware.b4a.objects.collections.JSONParser.NextArray(JSONParser.java:62)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    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.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.BA$3.run(BA.java:319)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5103)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
    at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Pause, UserClosed = false **
 

ivanomonti

Expert
Licensed User
Longtime User
solved my problem, I have to be more careful :-(

problem {Query:}

Query: category[{"Category":"Animal","SubCategory":"Dog Sitter"},{"Category":"Animal","SubCategory":"Cat Sitter"},{"Category":"Animal","SubCategory":"Veterinary"},{"Category":"Animal","SubCategory":"Other"},{"Category":"Work","SubCategory":"Painter"},{"Category":"Work","SubCategory":"Mason"},{"Category":"Work","SubCategory":"Elettrical"},{"Category":"Work","SubCategory":"Hydraulic"},{"Category":"Work","SubCategory":"Garden"},{"Category":"Work","SubCategory":"Other"},{"Category":"Assistance","SubCategory":"Garegivers"},{"Category":"Assistance","SubCategory":"Nurse"},{"Category":"Assistance","SubCategory":"General practitioner"},{"Category":"Assistance","SubCategory":"Dentist"},{"Category":"Assistance","SubCategory":"Gynecologist"},{"Category":"Assistance","SubCategory":"Physiotherapist"},{"Category":"Advice","SubCategory":"Mediator"},{"Category":"Advice","SubCategory":"Criminal Lawyer"},{"Category":"Advice","SubCategory":"Civil lawyer"},{"Category":"Advice","SubCategory":"Noary"},{"Category":"Advice","SubCategory":"Accountant"},{"Category":"Advice","SubCategory":"Business Consultant"},{"Category":"Personal Care","SubCategory":"Hairdresser"},{"Category":"Personal Care","SubCategory":"Beautician"},{"Category":"Personal Care","SubCategory":"Personal Trainer"},{"Category":"Personal Care","SubCategory":"Masseur"},{"Category":"Personal Care","SubCategory":"masseuse"},{"Category":"Animal","SubCategory":"All"},{"Category":"Work","SubCategory":"All"},{"Category":"Assistance","SubCategory":"All"},{"Category":"Advice","SubCategory":"All"},{"Category":"Personal Care","SubCategory":"All"}]
 

bluedude

Well-Known Member
Licensed User
Longtime User
How can we create something like below in code:

"checked": {
"computed": {
"address": [
"Line1",
"Line2",
"Line3"
],
"test": 1.4
},
},

Need to be able to create object arrays without keys etc.
 
Status
Not open for further replies.
Top