简体   繁体   中英

Parse JSON response for Google Maps Marker in Android

I am trying to retrieve a JSON response from the server, parse it and add markers to my map. I have a working map, and have added buttons to it, one of which I'd like to load markers from the server. Calling an action like this:

 public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnLoc:
                if(LocOn == 0){
                    googleMap.setMyLocationEnabled(true);
                    double lat= googleMap.getMyLocation().getLatitude();
                    double lng = googleMap.getMyLocation().getLongitude();
                    LatLng ll = new LatLng(lat, lng);
                    googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(ll, 18));
                    Loc.setBackgroundResource(R.drawable.loc);
                    LocOn = 1;
                    LoadMarkers.setText("Clear Markers");
                    GetMarkers markers = new GetMarkers();
                    markers.execute();


                } else {
                    LocOn = 0;
                    Loc.setBackgroundResource(R.drawable.noloc);
                    LoadMarkers.setText("Load Markers");
                    googleMap.clear();
                }

        }
    }

The "GetMarkers" action will call this:

class GetMarkers extends AsyncTask<User, Void, List<JMarker>>{

@Override
protected List<JMarker> doInBackground(User... params) {

    try {
        URL url = new URL("someurl.php");
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);
        String param = "username="+user.username+"&pw="+user.password;
        OutputStream out = conn.getOutputStream();
        DataOutputStream dataOut = new DataOutputStream(out);
        dataOut.writeBytes(param.trim());

        InputStream in = conn.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String line;
        StringBuilder builder = new StringBuilder();
        while((line = reader.readLine()) != null) {
            builder.append(line);
        }
        reader.close();
        String response = builder.toString();

        System.out.println(response); //This works, I'm getting a JSON response. Just need to parse it and return it to onPostExecute for processing. 

    }

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

    return null; //This will eventually return the JSON object
}
@Override
protected void onPostExecute(List<JMarker> jMarkers) {
    for(JMarker marker: jMarkers) {
        LatLng position = new LatLng(marker.LAT, marker.LNG);
        googleMap.addMarker(new MarkerOptions().position(position));
    }
}

}

The onPostExecute, am trying to add the eventually returned markers to the map.

I am hoping someone can help me out. Thank you in advance.

u have NPE in Map.java at line 148 i suppose

I suppose this is

BufferedReader reader = new BufferedReader(new InputStreamReader(in));

meaning your input stream is null.

two things here:

1) you should close your OutputStream before get response (out.close())

2) when getting response if code>200 you will not get anything from conn.getInputStream(); but from conn.getErrorStream() mening there is server error.

you can apply smth like that:

 StringBuffer response = new StringBuffer();
    System.out.println(conn.getResponseCode());
    try {
        BufferedReader in;

        if (conn.getResponseCode() > 299) {
            in = new BufferedReader(
                    new InputStreamReader(conn.getErrorStream()));
        } else {
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
        }
        String inputLine;


        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

    } catch (Exception ex) {
        ex.printStackTrace();
    }

However I would drop the AsyncTask I would use http client as Retrofit or Volley as it handles gracefully lots of http scenarios.

The answers and comments I received helped me "scratch my head" and arrive at this answer. The reason the app was not working, and crashing, is because I was passing null values, to the parameters. Once I passed the information along, I was able to get the JSON response, create a JSONArray and return that. Once it was sent to the onPostExecute, I parsed the JSONArray there, and added the markers. Working code:

First, I initiate the task.

GetMarkers markers = new GetMarkers();
markers.execute(user); //pass the user to the task

Task:

class GetMarkers extends AsyncTask<User, Void, JSONArray>{

        User markeruser = new User(userLocalStore.getLoggedInUser().username, userLocalStore.getLoggedInUser().password);
        JSONArray jsonarray = null;
        @Override
        protected JSONArray doInBackground(User... params) {

            try {
                URL url = new URL("https://someurl.com/file.php");
                HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
                String param = "Username="+markeruser.username+"&pw="+markeruser.password;
                OutputStream out = conn.getOutputStream();
                DataOutputStream dataOut = new DataOutputStream(out);
                dataOut.writeBytes(param.trim());

                InputStream in = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String line;
                StringBuilder builder = new StringBuilder();
                while((line = reader.readLine()) != null) {
                    builder.append(line);
                }
                reader.close();
                String response = builder.toString();

                jsonarray = new JSONArray(response);
            }

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

            return jsonarray;
        }

        @Override
        protected void onPostExecute(JSONArray jsonarray) {

            try {

                for(int i=0; i<jsonarray.length(); i++){
                    JSONObject obj = jsonarray.getJSONObject(i);

                    String PT = obj.getString("NUMBER");
                    Double LAT = obj.getDouble("LATITUDE");
                    Double LNG = obj.getDouble("LONGITUDE");
                    LatLng position = new LatLng(LAT, LNG);

                    String title = "PT: " + PT;

                    googleMap.addMarker(new MarkerOptions().position(position).title(title).icon(BitmapDescriptorFactory.fromResource(R.drawable.red)));
                }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM