Android API 15-18 | JSONObject compatibility issue

  android, java, json

The Problem

In the Android versions 15 to 18 the parsing of a JSON-String using the org.json.JSONObject class does not work the same as it does on newer versions.

String someWorkingJsonString = "{"":{array:[{text..."; 
System.out.println( new JSONObject( someWorkingJsonString ) );
// output on Android 5.1 (API 22) [working]
I/System.out: {"":{"array":[{"text":...

// output on Android 3.2 (API 16) [messed up double quotes]
I/System.out: {"":"{array:[{text:...

The Cause Of The Problem

Taking a close look at the org.json.JSONObject source code reveals, that in version 19 the use of a new warp() method was implemented in line 138.

// source code on Android API 15 - 18 [messed up double quotes]
/* 138 */  nameValuePairs.put(key, entry.getValue());

// source code on Android API 19 and up [working]
/* 138 */  nameValuePairs.put(key, wrap(entry.getValue()));

// implementation of the warp method on Android API 19 and up
    /**
     * Wraps the given object if necessary.
     *
     * <p>If the object is null or , returns {@link #NULL}.
     * If the object is a {@code JSONArray} or {@code JSONObject}, no wrapping is necessary.
     * If the object is {@code NULL}, no wrapping is necessary.
     * If the object is an array or {@code Collection}, returns an equivalent {@code JSONArray}.
     * If the object is a {@code Map}, returns an equivalent {@code JSONObject}.
     * If the object is a primitive wrapper type or {@code String}, returns the object.
     * Otherwise if the object is from a {@code java} package, returns the result of {@code toString}.
     * If wrapping fails, returns null.
     */
    public static Object wrap(Object o) {
        if (o == null) {
            return NULL;
        }
        if (o instanceof JSONArray || o instanceof JSONObject) {
            return o;
        }
        if (o.equals(NULL)) {
            return o;
        }
        try {
            if (o instanceof Collection) {
                return new JSONArray((Collection) o);
            } else if (o.getClass().isArray()) {
                return new JSONArray(o);
            }
            if (o instanceof Map) {
                return new JSONObject((Map) o);
            }
            if (o instanceof Boolean ||
                o instanceof Byte ||
                o instanceof Character ||
                o instanceof Double ||
                o instanceof Float ||
                o instanceof Integer ||
                o instanceof Long ||
                o instanceof Short ||
                o instanceof String) {
                return o;
            }
            if (o.getClass().getPackage().getName().startsWith("java.")) {
                return o.toString();
            }
        } catch (Exception ignored) {
        }
        return null;
    }

The Question

How do I patch out the discribed problem with the older versions of android?

Thanks in advance

Source: Android Questions

LEAVE A COMMENT