2017-10-21 80 views
0

在我的應用程序中,我使用Google Place Picker來獲取用戶將要前往的位置座標以及Google API方向我在KM中獲取距離,但有時我在日誌中得到此錯誤,沒有得到的距離和時間:Google API Directions在閱讀時發生錯誤JSONObejct

10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err: org.json.JSONException: Index 0 out of range [0..0) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at org.json.JSONArray.get(JSONArray.java:293) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at org.json.JSONArray.getJSONObject(JSONArray.java:521) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at com.ddz.assistenteauto.Fragments.TravelFragment$4.onResponse(TravelFragment.java:249) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at com.ddz.assistenteauto.Fragments.TravelFragment$4.onResponse(TravelFragment.java:236) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at android.os.Handler.handleCallback(Handler.java:739) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at android.os.Handler.dispatchMessage(Handler.java:95) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at android.os.Looper.loop(Looper.java:148) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at android.app.ActivityThread.main(ActivityThread.java:7325) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at java.lang.reflect.Method.invoke(Native Method) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
10-21 20:30:23.326 4920-4920/com.ddz.assistenteauto W/System.err:  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

在這裏,我如何發送請求,谷歌與HTTP請求:

private void getDistanceTime(TravelInfo obj){ 

    Log.d(TAG, "getDistanceTime()"); 
    // Instantiate the RequestQueue. 
    RequestQueue queue = Volley.newRequestQueue(getActivity()); 

    String url = "http://maps.googleapis.com/maps/api/directions/json?origin=" + obj.getStartLat() + "," + obj.getStartLng() + "&destination=" + obj.getEndLat() + "," + obj.getEndLng() + "&mode=driving&sensor=false"; 

    // Request a string response from the provided URL. 
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, 
      new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        // Display the first 500 characters of the response string. 
        //mTextView.setText("Response is: "+ response.substring(0,500)); 
        //Log.i(TAG,"Response is: "+ response); 

        try { 
         JSONObject jsonObject = new JSONObject(response); 

         // routesArray contains ALL routes 
         JSONArray routesArray = jsonObject.getJSONArray("routes"); 
         // Grab the first route 
         JSONObject route = routesArray.getJSONObject(0); 
         // Take all legs from the route 
         JSONArray legs = route.getJSONArray("legs"); 
         // Grab first leg 
         JSONObject leg = legs.getJSONObject(0); 
         //take travel distance 
         JSONObject distanceObject = leg.getJSONObject("distance"); 
         String distance = distanceObject.getString("text"); 
         //Take travel duration 
         JSONObject durationObject = leg.getJSONObject("duration"); 
         String duration = durationObject.getString("text"); 

         //Set distance and duration to the class infoTravel that contain coordinates 
         setDistanceTime(distance, duration); 


        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 

       } 
      }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      //mTextView.setText("That didn't work!"); 
      Log.i(TAG,"That didn't work!"); 
     } 
    }); 
    // Add the request to the RequestQueue. 
    queue.add(stringRequest); 

} 

有人能幫忙嗎?

我可以從PlacePicker獲取用戶位置嗎? 從現在我用這個獲取用戶的位置:

private void getUserLocation() { 

    Log.i(TAG, "getUserLocation()"); 
    if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
      && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     // TODO: Consider calling 
     // ActivityCompat#requestPermissions 
     // here to request the missing permissions, and then overriding 
     // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
     //           int[] grantResults) 
     // to handle the case where the user grants the permission. See the documentation 
     // for ActivityCompat#requestPermissions for more details. 
     return; 
    } 
    mFusedLocationClient.getLastLocation() 
      .addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() { 
       @Override 
       public void onSuccess(Location location) { 
        // Got last known location. In some rare situations this can be null. 
        if (location != null) { 
         // Logic to handle location object 
         String stringStartLat, stringStartLng; 

         travelInfo.setStartLat(location.getLatitude()); 
         travelInfo.setStartLng(location.getLongitude()); 
         stringStartLat = Double.toString(travelInfo.getStartLat()); 
         stringStartLng = Double.toString(travelInfo.getStartLng()); 
         //Set the TextView in the fragment with start coordinates 
         startLatView.setText(stringStartLat); 
         startLngView.setText(stringStartLng); 

         if (travelInfo.getEndLat() != 0 && travelInfo.getEndLng() != 0) { 
          Log.i(TAG, "Dentro if userlocation"); 
          getDistanceTime(travelInfo); 
         } 
        } 
       } 
      }); 
} 

編輯

當我得到的JSON的錯誤,我收到來自谷歌API這個JSON

10-21 20:54:18.965 22814-22814/com.ddz.assistenteauto I/TravelFragment: Response is: { 
                      "error_message" : "You have exceeded your daily request quota for this API. We recommend registering for a key at the Google Developers Console: https://console.developers.google.com/apis/credentials?project=_", 
                      "routes" : [], 
                      "status" : "OVER_QUERY_LIMIT" 
                     } 

編輯

我添加網址的關鍵但仍然出現錯誤:

String url = "http://maps.googleapis.com/maps/api/directions/json?origin=" + obj.getStartLat() + "," + obj.getStartLng() + "&destination=" + obj.getEndLat() + "," + obj.getEndLng() + "&mode=driving&AIza*****************FI"; 

EDIT 2現在的關鍵我得到這個錯誤:

10-22 15:24:35.540 27362-27362/com.ddz.assistenteauto I/TravelFragment: Response is: { 
                      "error_message" : "Requests to this API must be over SSL. Load the API with \"https://\" instead of \"http://\".", 
                      "routes" : [], 
                      "status" : "REQUEST_DENIED" 

所以我的HTTP更改爲https ......,讓我們看看 }

+1

在上次更新中,您看起來像缺少一個'&key =',它應該是'&mode = driving&key = AIza ***************** FI'而不是'&mode =駕駛&AIza ***************** FI' – xomena

+0

你是對的!謝謝....看看現在是否工作:) – Dario

回答

0

錯誤消息是很清楚,說你超出配額且您的Directions API請求不使用API​​密鑰。

請注意,即使您沒有發送太多的請求,無密鑰訪問Google Web服務也會使用共享配額,其他沒有API密鑰的用戶可以發送很多請求並使用通用配額。

爲了解決此問題,您必須在Google Cloud開發者控制檯中創建項目,請激活Directions API Web服務並生成API密鑰。然後你就可以在你的請求應用關鍵:

String url = "http://maps.googleapis.com/maps/api/directions/json?origin=" + obj.getStartLat() + "," + obj.getStartLng() + "&destination=" + obj.getEndLat() + "," + obj.getEndLng() + "&mode=driving&key=YOUR_API_KEY";

您可以安全地刪除sensor這是過時的,已不再需要。

欲瞭解更多詳情,請參閱路線API文檔:

https://developers.google.com/maps/documentation/directions/get-api-key

UPDATE

你也應該正確處理響應status的可能值。有時你可以得到ZERO_RESULTS,NOT_FOUND或UNKNOWN_ERROR,在這種情況下,routes元素不存在,或者在響應中爲空,這會導致您在代碼中觀察到的異常。

try { 
    JSONObject jsonObject = new JSONObject(response); 

    //Get status first 
    String status = jsonObject.getString("status"); 

    if (status.equals("OK")) { 
     // routesArray contains ALL routes 
     JSONArray routesArray = jsonObject.getJSONArray("routes"); 
     // Grab the first route 
     JSONObject route = routesArray.getJSONObject(0); 
     // Take all legs from the route 
     JSONArray legs = route.getJSONArray("legs"); 
     // Grab first leg 
     JSONObject leg = legs.getJSONObject(0); 
     //take travel distance 
     JSONObject distanceObject = leg.getJSONObject("distance"); 
     String distance = distanceObject.getString("text"); 
     //Take travel duration 
     JSONObject durationObject = leg.getJSONObject("duration"); 
     String duration = durationObject.getString("text"); 
     //Set distance and duration to the class infoTravel that contain coordinates 
     setDistanceTime(distance, duration); 
    } else if (status.equals("NOT_FOUND")) { 
     //TODO: handle not found 
    } else if (status.equals("ZERO_RESULTS")) { 
     //TODO: handle zero results 
    } else if (status.equals("OVER_QUERY_LIMIT")) { 
     //TODO: handle over query limit 
    } 
    ..... 

} catch (JSONException e) { 
    e.printStackTrace(); 
} 

      } 

希望這有助於!

+0

謝謝,是的,我有一個谷歌api鍵包括在清單,我認爲我採取自動....我把api鍵入url ...我會嘗試如果問題解決了。 是的,我已經激活了Google Cloud和Places的方向:) 你知道女巫街道發生在JSON包含的「距離」嗎? 是旅行的最佳/短途街道? – Dario

+1

您在清單中使用的API密鑰具有Android應用程序限制,它不適用於Web服務。您必須生成新的API密鑰才能在Web服務中使用它。請注意,Web服務API密鑰僅支持IP限制,但在移動應用程序中,您無法知道安裝該應用程序的設備的IP地址,因此請嘗試使用不受限制的密鑰。 – xomena

+0

路線API通常返回最快的路線,沒有辦法獲得最短路線。 – xomena

相關問題