如何解析类似字符串的不完整JSON

时间:2017-08-26 17:17:37

标签: java android json

我正在通过BLE从我的外围设备读取一些数据到我的Android应用程序。 该应用程序以JSON格式从BLE设备获取数据。一切正常,除非在少数情况下我从BLE设备获得不完整的JSON字符串(我无法控制它,我需要处理我收到的任何内容。最初,我得到一个简单的JSON数组,如

[wifi1, wifi2, wifi3, wifi4, wifi5]

因此,如果获取不完整的字符串,我将处理JSON解析异常并使用字符串标记符并简单地解析每个标记并获取wifi名称

StringTokenizer tokens = new StringTokenizer(new String(bytes), ",");
        int size =  tokens.countTokens();
        HashMap<String, Object> map;
        for (int i = 0; i < size; i++) {
            map = new HashMap<String, String>();   
            map.put("Wifi, tokens.nextToken().replace("\"", "").replace("]", "").replace("[", ""));

但是现在JSON字符串已被更改并包含许多其他信息,这是我得到的新JSON

[{"ssid":"Wifi1","rssi":-50,"encrypt":"on"},{"ssid":"wifi2","rssi":-61,"encrypt":"on"},{"ssid":"wifi3","rssi":-81,"encrypt":"of

现在,如果我以这种格式获得不完整的JSON(如上所述),我无法解析wifi名称并使用StringTokenizer加密信息(它变得复杂和丑陋)。 你有任何想法如何解析这些wifi名称和从上面的字符串加密信息。任何建议都会有很大的帮助。

1 个答案:

答案 0 :(得分:1)

感谢@pskink和@Andreas建议流式JSON解析器,我尝试了这个,它适用于我。希望它对其他人也有帮助。

 public void parseWifiJSON(byte[] bytes)
 {
   trackerWifiScanList = readJsonStream(bytes);
   // do stuff with your list
 } 

 public List<WifiScan> readJsonStream(byte[] bytes)  {

    JsonReader reader = new JsonReader(new StringReader(new String(bytes)));
    List<WifiScan> resultList = null;
    try {
        resultList = readMessagesArray(reader);
        reader.close();
    } catch (IOException e) {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ex) {
                // Do nothing
            }
        }
    }

    return resultList;
}

public List<WifiScan> readMessagesArray(JsonReader reader) throws IOException {
    ArrayList<WifiScan> messages = new ArrayList<WifiScan>();

    try {
        reader.beginArray();
        while (reader.hasNext()) {
            messages.add(readMessage(reader));
        }
    }catch (Exception e)
    {
        if (reader != null) {
            try {
                reader.endArray();
            } catch (IOException ex) {
                // Do nothing
            }
        }
    }
    return messages;
}

public WifiScan readMessage(JsonReader reader) throws IOException {
    String wifissid ="";
    int rssi = 0;
    String encrypt="";
    WifiScan wifInfo = new WifiScan();
    try {
        reader.beginObject();
        while (reader.hasNext()) {
            String name = reader.nextName();
            if (name.equals("ssid")) {
                wifissid = reader.nextString();
            } else if (name.equals("rssi")) {
                rssi = reader.nextInt();
            } else if (name.equals("encrypt")) {
                encrypt = reader.nextString();
            } else {
                reader.skipValue();
            }
        }
        reader.endObject();
        wifInfo.setSsid(wifissid);
        wifInfo.setRssi(rssi);
        wifInfo.setEncrypt(encrypt);
    }catch (Exception e)
    {
        // JSON was not complete so just set a dummy object.
        wifInfo.setSsid("");
        wifInfo.setRssi(0);
        wifInfo.setEncrypt("");
    }
    return wifInfo;
}