2014-08-27 70 views
0

我已經搜索並搜索了適用的答案,但是我找到的所有內容都不適合。org.json.JSONException帶有Google Places

我使用了教程(http://code.tutsplus.com/tutorials/android-sdk-working-with-google-maps-displaying-places-of-interest--mobile-16145)來識別當前位置的當地場所(餐廳等)。但是,與本教程不同,我的本地地方沒有出現。

我的清單如下:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.WreckinApp.MaJoRProduct.wbiassistant" > 

<permission 
    android:name="com.WreckinApp.MaJoRProduct.wbiassistant.permission.MAPS_RECEIVE" 
    android:protectionLevel="signature"/> 
<uses-permission android:name="com.WreckinApp.MaJoRProduct.wbiassistant.MAPS_RECEIVE"/> 

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

<uses-feature 
    android:glEsVersion="0x00020000" 
    android:required="true" /> 


<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 

    <meta-data 
     android:name="com.google.android.maps.v2.API_KEY" 
     android:value="MAPS_API_KEY"/> 
    <meta-data 
     android:name="com.google.android.gms.version" 
     android:value="@integer/google_play_services_version" /> 

    <activity 
     android:name=".splash" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity android:name=".main" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboardHidden|orientation|screenSize"> 
    </activity> 
    <activity android:name=".contact" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboardHidden|orientation|screenSize"> 
    </activity> 
    <activity android:name=".map" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboardHidden|orientation|screenSize"> 
    </activity> 
    <activity android:name=".gallery" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboardHidden|orientation|screenSize"> 
    </activity> 
    <activity android:name=".link" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboardHidden|orientation|screenSize"> 
    </activity> 
    <activity android:name=".split" 
     android:screenOrientation="portrait" 
     android:configChanges="keyboardHidden|orientation|screenSize"> 
    </activity> 


</application> 

</manifest> 

包含地圖的活動如下:

package com.WreckinApp.MaJoRProduct.wbiassistant; 

import android.app.Activity; 
import android.content.Context; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.util.Log; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.StatusLine; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.UnsupportedEncodingException; 
import java.net.URLEncoder; 

import android.app.Activity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import com.google.android.gms.maps.CameraUpdateFactory; 
import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.MapFragment; 
import com.google.android.gms.maps.model.BitmapDescriptorFactory; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.Marker; 
import com.google.android.gms.maps.model.MarkerOptions; 
import android.location.Location; 
import android.location.LocationManager; 
import android.content.Context; 
import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.UnsupportedEncodingException; 
import java.net.URLEncoder; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.StatusLine; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.DefaultHttpClient; 

import android.os.AsyncTask; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 
import android.util.Log; 


public class map extends Activity { 
private GoogleMap map; 
private LocationManager locMan; 
private Marker userMarker; 
private int userIcon, foodIcon, drinkIcon, shopIcon, otherIcon; 
private Marker[] placeMarkers; 
private final int MAX_PLACES = 10; 
private MarkerOptions[] places; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.map); 
    userIcon = R.drawable.yellow_point; 
    foodIcon = R.drawable.red_point; 
    drinkIcon = R.drawable.blue_point; 
    shopIcon = R.drawable.green_point; 
    otherIcon = R.drawable.purple_point; 

    if(map==null) { 
     //map not instantiated yet 
     map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); 
    } 

    if(map != null){ 
     //ok - proceed 
    } 
    map.setMapType(GoogleMap.MAP_TYPE_NORMAL); 
    placeMarkers = new Marker[MAX_PLACES]; 
    updatePlaces(); 
} 
private void updatePlaces(){ 
    locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 
    Location lastLoc = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
    double lat = lastLoc.getLatitude(); 
    double lng = lastLoc.getLongitude(); 

    //update location 

    LatLng lastLatLng = new LatLng(lat, lng); 
    if(userMarker!=null){userMarker.remove();} 
    userMarker = map.addMarker(new MarkerOptions() 
      .position(lastLatLng) 
      .title("You are here") 
      .icon(BitmapDescriptorFactory.fromResource(userIcon)) 
      .snippet("Your last recorded location")); 
    map.animateCamera(CameraUpdateFactory.newLatLng(lastLatLng), 3000, null); 

    String types = "food|bar|store|museum|art_gallery"; 
    try { 
     types = URLEncoder.encode(types, "UTF-8"); 
    } catch (UnsupportedEncodingException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    String placesSearchStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/output?" + 
      "parameters" + 
      "json?location="+lat+","+lng+ 
      "&radius=500&sensor=true" + 
      "&types=" + types + 
      "AIzaSyASEbnPuqb-_Y8N_CqBfqSw9ZPVLWQt0lQ"; 

    new GetPlaces().execute(placesSearchStr); 
} 

private class GetPlaces extends AsyncTask<String, Void, String> { 
    //fetch and parse place data 

    @Override 
    protected String doInBackground(String... placesURL) { 
     //fetch places 

     StringBuilder placesBuilder = new StringBuilder(); 

     //process search parameter string(s) 
     for (String placeSearchURL : placesURL) { 
      //execute search 

      HttpClient placesClient = new DefaultHttpClient(); 
      try { 
       //try to fetch the data 
       HttpGet placesGet = new HttpGet(placeSearchURL); 
       HttpResponse placesResponse = placesClient.execute(placesGet); 
       StatusLine placeSearchStatus = placesResponse.getStatusLine(); 

       if (placeSearchStatus.getStatusCode() == 200) { 
        //we have an OK response 
        HttpEntity placesEntity = placesResponse.getEntity(); 
        InputStream placesContent = placesEntity.getContent(); 
        InputStreamReader placesInput = new InputStreamReader(placesContent); 
        BufferedReader placesReader = new BufferedReader(placesInput); 
        String lineIn; 
        while ((lineIn = placesReader.readLine()) != null) { 
         placesBuilder.append(lineIn); 
        } 
       } 
      } 
      catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 
     return placesBuilder.toString(); 
    } 
    protected void onPostExecute(String result) { 
     //parse place data returned from Google Places 
     if(placeMarkers!=null){ 
      for(int pm=0; pm<placeMarkers.length; pm++){ 
       if(placeMarkers[pm]!=null) 
        placeMarkers[pm].remove(); 
       try { 
        //parse JSON 
        JSONObject resultObject = new JSONObject(result); 
        JSONArray placesArray = resultObject.getJSONArray("results"); 
        places = new MarkerOptions[placesArray.length()]; 
        //loop through places 
        for (int p=0; p<placesArray.length(); p++) { 
         //parse each place 
         boolean missingValue=false; 
         LatLng placeLL=null; 
         String placeName=""; 
         String vicinity=""; 
         int currIcon = otherIcon; 
         try{ 
          //attempt to retrieve place data values 
          missingValue=false; 
          JSONObject placeObject = placesArray.getJSONObject(p); 
          JSONObject loc = placeObject.getJSONObject("geometry").getJSONObject("location"); 
          placeLL = new LatLng(
            Double.valueOf(loc.getString("lat")), 
            Double.valueOf(loc.getString("lng"))); 
          JSONArray types = placeObject.getJSONArray("types"); 
          for(int t=0; t<types.length(); t++) { 
           //what type is it 

           String thisType = types.get(t).toString(); 
           if (thisType.contains("food")) { 
            currIcon = foodIcon; 
            break; 
           } else if (thisType.contains("bar")) { 
            currIcon = drinkIcon; 
            break; 
           } else if (thisType.contains("store")) { 
            currIcon = shopIcon; 
            break; 
           } 
          } 
          vicinity = placeObject.getString("vicinity"); 
          placeName = placeObject.getString("name"); 

         } 
         catch(JSONException jse){ 
          missingValue=true; 
          jse.printStackTrace(); 
         } 
         if(missingValue) places[p]=null; 
         else 
          places[p]=new MarkerOptions() 
            .position(placeLL) 
            .title(placeName) 
            .icon(BitmapDescriptorFactory.fromResource(currIcon)) 
            .snippet(vicinity); 
        } 
       } 
       catch (Exception e) { 
        e.printStackTrace(); 
       } 
       if(places!=null && placeMarkers!=null){ 
        for(int p=0; p<places.length && p<placeMarkers.length; p++){ 
         //will be null if a value was missing 
         if(places[p]!=null) 
          placeMarkers[p]=map.addMarker(places[p]); 
        } 
       } 
      } 
     } 

    } 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.splash, menu); 
    return true; 
} 


@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_settings) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 
} 

我logcat的錯誤看起來像這樣一遍又一遍:

08-27 18:07:02.577 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method) 
08-27 18:07:02.577 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515) 
08-27 18:07:02.577 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
08-27 18:07:02.577 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
08-27 18:07:02.577 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at dalvik.system.NativeStart.main(Native Method) 
08-27 18:07:02.577 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ org.json.JSONException: End of input at character 0 of 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at org.json.JSONTokener.syntaxError(JSONTokener.java:450) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at org.json.JSONTokener.nextValue(JSONTokener.java:97) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at org.json.JSONObject.<init>(JSONObject.java:155) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at org.json.JSONObject.<init>(JSONObject.java:172) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at com.WreckinApp.MaJoRProduct.wbiassistant.map$GetPlaces.onPostExecute(map.java:176) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at com.WreckinApp.MaJoRProduct.wbiassistant.map$GetPlaces.onPostExecute(map.java:130) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at android.os.AsyncTask.finish(AsyncTask.java:632) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at android.os.AsyncTask.access$600(AsyncTask.java:177) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at android.os.Looper.loop(Looper.java:136) 
08-27 18:07:02.587 26474-26474/com.WreckinApp.MaJoRProduct.wbiassistant W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5001) 

我認識的是map.java:130

private class GetPlaces extends AsyncTask<String, Void, String> 

和map.java:176

JSONObject resultObject = new JSONObject(result); 

,但我不知道什麼是錯的每一行看到,因爲我去一步教程一步。他們之前在測試應用程序中出現過一次,但我從那以後(愚蠢地)刪除了它,我只需要當地的地方出現,而他們不是。我哪裏錯了?

+0

提出請求時URL的外觀如何?如果你把它放在瀏覽器中並查看結果,JSON看起來是否正確? – rindress 2014-08-28 00:33:55

回答

0

我認爲你的代碼沒有問題。請檢查您的網址。

String placesSearchStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/output?" + 
     "parameters" + 
     "json?location="+lat+","+lng+ 
     "&radius=500&sensor=true" + 
     "&types=" + types + 
     "AIzaSyASEbnPuqb-_Y8N_CqBfqSw9ZPVLWQt0lQ"; 

您的網址包含單詞「output?」它意味着要麼json或xml輸出和「參數」必須被省略。它應該看起來像這樣:

String placesSearchStr = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?" + 
     "location="+lat+","+lng+ 
     "&radius=500&sensor=true" + 
     "&types=" + types +"&key=AIzaSyASEbnPuqb-_Y8N_CqBfqSw9ZPVLWQt0lQ"; 

希望它有幫助。

+0

似乎已經完成了這個訣竅。我謝謝你!這一直困擾着我幾個星期。在下一部分!嗚呼! – TOUKOD 2014-08-28 15:52:09

+0

不客氣。 – yhel 2014-08-29 01:50:31

0

在您的while循環中,讀取響應時,讀取更多行時存在。 但您插入時沒有換行符。

我不確定它是否會有所幫助,但可能會損害Json編碼。

  while ((lineIn = placesReader.readLine()) != null) { 
        placesBuilder.append(lineIn + "\n"); 
       } 
+0

不幸的是,沒有改變,但我非常感謝您的幫助。 – TOUKOD 2014-08-27 23:24:18