2016-09-06 105 views
0

我想从Android Studio中MySQL数据库分析JSONArray,但我得到以下异常:解析JSONArray双Android Studio中

org.json.JSONException: Value {"success":false,"0":{"success":false,"marker_id":null,"lat":null,"lng":null,"snippet":null},"1":{"success":false,"marker_id":null,"lat":null,"lng":null,"snippet":null},"2":{"success":false,"marker_id":null,"lat":null,"lng":null,"snippet":null},"3":{"success":false,"marker_id":null,"lat":null,"lng":null,"snippet":null}} of type org.json.JSONObject cannot be converted to JSONArray 

我所试图做的是解析包含几个标记LatLng的双精度值,然后将这些标记放置在Google地图中。

用于放置标记和发出请求

代码:

Response.Listener<String> responseListener = new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 
         try { 

          JSONArray jsonResponse = new JSONArray(response); 
          Log.i("RESPONSE:", "[" + jsonResponse + "]"); 


          for (int i = 0; i < response.length(); i++) { 

           //boolean success = jsonResponse.getBoolean("success"); 
           //double lat = jsonResponse.getDouble("lat"); 
           //double lng = jsonResponse.getDouble("lng"); 
           //int snippet = jsonResponse.getInt("snippet"); 



           //LatLng Mplace = new LatLng(lat, lng); 

           //MarkerOptions marker = new MarkerOptions().position(Mplace).title("Marker").snippet("Snippet:" + "0"); 
           //mMap.addMarker(marker); 


          } 


         } catch (JSONException e) { 
          e.printStackTrace(); 
          Log.i("RESPONSE:", "[" + response + "]"); 
          Toast.makeText(getApplicationContext(), 
            "Error: " + e.getMessage(), 
            Toast.LENGTH_LONG).show(); 
         } 

        } 

       }; 

       MarkerRequest markerRequest = new MarkerRequest(responseListener); 
       RequestQueue queue = Volley.newRequestQueue(AllMarkersActivity.this); 
       queue.add(markerRequest); 

现在我都谈到了标记的实际配售,这是当我得到上述的异常。当我删除评论我得到这个红色短信:

getDouble (int) cannot be applied to (java.lang.String) 

这里是我的请求代码:

public class MarkerRequest extends StringRequest { 
private static final String MARKER_REQUEST_URL = "http://simonjensen.comxa.com/GetMarkers.php"; 
private Map<String, String> params; 
//private JSONObject data = new JSONObject("http://simonjensen.comxa.com/GetMarkers.php"); 

public MarkerRequest(Response.Listener<String> listener){ 
    super(Request.Method.POST, MARKER_REQUEST_URL, listener, null); 
    params = new HashMap<>(); 
} 
@Override 
public Map<String, String> getParams() { 
    return params; 
} 

这里是我的PHP脚本:

<?php 
$con = mysqli_connect("myhost", "myuser", "mypass", "mydatabase"); 

/*$statement = mysqli_prepare($con); 

$sql = "SELECT * FROM markers ORDER BY marker_id ASC "; 
$strSQL = "SELECT * FROM `markers` ORDER BY marker_id ASC "; 

$objQuery = mysql_query($statement, $strSQL) or die(mysql_error()); 
$arrRows = array(); 
$arryItem = array();*/ 

$statement = mysqli_prepare($con, "SELECT * FROM markers ORDER BY marker_id ASC "); 
    mysqli_stmt_execute($statement); 
//mysqli_stmt_bind_result($statement, $colmarker_id, $collat, $collng, $colsnippet); 

//$response = array(); 
$arrRows = array(); 
$arryItem = array(); 
    //$response["success"] = false; 
$arrRows["success"] = false; 
$arryItem["success"] = false; 

while(mysqli_stmt_fetch($statement)) { 
    $arryItem["marker_id"] = $arr["marker_id"]; 
    $arryItem["lat"] = $arr["lat"]; 
    $arryItem["lng"] = $arr["lng"]; 
    $arryItem["snippet"] = $arr["snippet"]; 
    $arrRows[] = $arryItem; 
} 

echo json_encode($arrRows); 
?> 

所以我的问题可以缩小到这个:

我如何解析一个JSONArray(在一个数组内?),我如何在那个JSONArray内解析一个double值?

这将是一个代码示例很好,因为我仍然在学习:)

谢谢!

+0

你的json不包含数组,它具有单个对象内的对象。数组由“[”表示。 –

回答

0

正如您回应含有JSON对象和外JSON对象包含在内JSON对象。因此,首先在JSON对象中解析它,然后获取Lat和lng。试试这段代码:

JSONObject jsonObject = new JSONObject(response); 
    Iterator<String> keys = jsonObject.keys(); 
    while(keys.hasNext()) 
    { 
     String key = keys.next(); 
       if(!key.equals("success")){ // or use this if your keys are always in digits form.. if(TextUtils.isDigitsOnly(key)) 
        Log.v("category key", key); 
        JSONObject innerJObject = jsonObject.getJSONObject(key); 
        String lat_str = innerJObject.getString("lat"); 
        double lat = 0.0, lng = 0.0; 

        if(!TextUtils.isEmpty(lat_str) &&  TextUtils.isDigitsOnly(lat_str)) 
         lat = Double.parseDouble(lat_str); 

        String lng_str = innerJObject.getString("lng"); 

        if(!TextUtils.isEmpty(lng_str) && TextUtils.isDigitsOnly(lng_str)) 
         lng = Double.parseDouble(lng_str); 

       } 
    } 

在这个块中添加异常处理。这可能有帮助!

+0

我尝试这样做,得到了异常:org.json.JSONException:值在java.lang.Boolean类型的成功虚假不能被转换为JSONObject的 –

+0

我已经编辑我的答案现在检查。这是因为我们拥有“成功”并不是它的一个布尔关键。所以,现在检查并让我知道:) –

+0

或者,如果您认为您的密钥始终为数字形式,则您可以使用此TextUtils.isDigitsOnly(key)而不是!key.equals(“success”)。 –

0

更改此

JSONArray jsonResponse = new JSONArray(response); 

TO

JSONObject jsonResponse = new JSONObject(response); 

获取经纬度值使用以下。

double lat = jsonResponse.getJSONObject("0").optDouble("lat"); 
+0

我已经试图做到这一点,但后来我得到:org.json.JSONException:拉特没有价值 - 这使我想我必须做aprse JSONArray –

+0

看到我更新的答案。 – Amy

+0

谢谢!这是一个让它工作的东西,它现在不会给我任何例外,但是我仍然在我的JSON响应中获得空值。是什么赋予了?响应是这样的,并将标记置于gmaps的中间:I/RESPONSE:{“success”:false,“0”:{“success”:false,“marker_id”:null,“lat”:null, “LNG”:空, “片段”:空}, “1”:{ “成功”:假的, “marker_id”:空, “LAT”:空, “LNG”:空, “片段”:空}” 2 “:{” 成功 “:假” marker_id “:NULL,” LAT “:NULL,” LNG “:NULL,” 片断 “:空},” 3 “:{” 成功 “:假” marker_id“: null,“lat”:null,“lng”:null,“snippet”:null}} –

0

似乎你传递的是字符串数据而不是double值。试着这样做:

String lat_str = jsonResponse.getString("lat"); 
double lat = Double.parseDouble(lat_str); 
String lng_str = jsonResponse.getString("lng"); 
double lng = Double.parseDouble(lng_str); 
+0

我试着做这两个与JSONArray和JSONObject,与数组一样,它给了我与double相同的红色文本,就像这样:getString(int)不能应用于(java.lang.String),并使用JSONObject给它:org.json.JSONException:没有lat –

0
try { 

       JSONArray jsonResponse = new JSONArray(response); 
       Log.i("RESPONSE:", "[" + jsonResponse + "]"); 
       for (int i = 0; i < jsonResponse.length(); i++) { 
        JSONObject obj = jsonResponse.getJSONObject(i); 



        boolean success = obj.getBoolean("success"); 
        double lat = obj.getDouble("lat"); 
        double lng = obj.getDouble("lng"); 
        int snippet = obj.getInt("snippet"); 


        LatLng Mplace = new LatLng(lat, lng); 
        MarkerOptions marker = new MarkerOptions().position(Mplace).title("Marker").snippet("Snippet:" + "0"); 
        mMap.addMarker(marker); 


       } 


      } catch (JSONException e) { 
       e.printStackTrace(); 
       Log.i("RESPONSE:", "[" + response + "]"); 
       Toast.makeText(getApplicationContext(), 
         "Error: " + e.getMessage(), 
         Toast.LENGTH_LONG).show(); 
      } 
+0

的值这似乎删除了红色文本错误,但我仍然得到JSON异常:org.json.JSONException:Value {“success”:false,“0”:{“success”:false,“marker_id “:空,” LAT “:空,” LNG “:空,” 片段 “:空},” 1 “:{” 成功 “:假的,” marker_id “:空,” LAT “:空,” LNG“:空, “片断”:空}, “2”:{ “成功”:假 “marker_id”:NULL, “LAT”:NULL, “LNG”:NULL, “片断”:空}, “3”:{ “成功”:false,“marker_id”:null,“lat”:null,“lng”:null,“snippet”:null}}类型为org.json.JSONObject ca不能转换为JSONArray –

+0

response =“[”+ response +“]”; 在JSONArray之前添加此行jsonResponse = new JSONArray(response); 和循环更新开始点 for(int i = 1; i

+0

就像其他两个答案一样,我很确定这是有效的,因为我得到一个编排器日志说:“我/编舞:跳过了33帧!应用程序可能在其主线程上做了太多工作。”这告诉我它可能加载太多(这意味着它必须工作,我猜)。只需要弄清楚如何在后台线程中做到这一点:)谢谢! –

0
Response.Listener<String> responseListener = new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        try { 

     JSONObject jsonResponse = new JSONObject(json); 


     boolean flag = true; 
     int i = 0; 
     while (flag) { 

      try { 
       JSONObject jsonInnerObject = new  JSONObject(jsonResponse.get(String.valueOf(i)).toString()); 
       Object success = jsonInnerObject.get("success"); 
       Object marker_id = jsonInnerObject.get("marker_id"); 
       Object lat = jsonInnerObject.get("lat"); 
       Object lng = jsonInnerObject.get("lng"); 
       Object snippet = jsonInnerObject.get("snippet"); 
       i++; 
      } catch (Exception e) { 
       flag = false; 
      } 


     } 



         } catch (JSONException e) { 
         e.printStackTrace(); 
         Log.i("RESPONSE:", "[" + response + "]"); 
         Toast.makeText(getApplicationContext(), 
           "Error: " + e.getMessage(), 
           Toast.LENGTH_LONG).show(); 
        } 
+0

当我这样做时,我没有得到logcat中记录的任何RESPONSE。但是,它并没有给我任何例外。我将如何去放置这种方法标记?谢谢! –

+0

@ SimonA.CallaghanJensen我没有做任何与响应,这就是为什么它没有显示,,,如果你调试这个你得到经纬度和其他值的响应在while循环,,,你可以做任何你想做的事情这里的值为 – Arslan

+0

我这样做,就像其他答案一样,我得到一个编排日志,上面写着:“I /编舞:跳过了33帧!应用程序可能在其主线程上做了太多工作。这告诉我它可能加载太多(这意味着它必须工作,我猜)。只需要弄清楚如何在后台线程中做到这一点:)谢谢! –