2016-09-06 54 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幀!應用程序可能在其主線程上做了太多工作。這告訴我它可能加載太多(這意味着它必須工作,我猜)。只需要弄清楚如何在後臺線程中做到這一點:)謝謝! –