【问题标题】:Parsing JSON data for weather app解析天气应用程序的 JSON 数据
【发布时间】:2016-09-11 19:02:50
【问题描述】:

我正在尝试显示从打开的天气地图中获得的天气数据。数据似乎位于 json 变量中,但我无法正确解析。

<current>
<city id="4459467" name="Cary">
<coord lon="-78.78" lat="35.79"/>
<country>US</country>
<sun rise="2016-09-11T10:55:38" set="2016-09-11T23:26:18"/>
</city>
<temperature value="304.23" min="302.15" max="305.37" unit="kelvin"/>    
<humidity value="45" unit="%"/>
<pressure value="1018" unit="hPa"/>
<wind>
<speed value="2.6" name="Light breeze"/>
<gusts/><direction value="0" code="N" name="North"/>
</wind>
<clouds value="75" name="broken clouds"/>
<visibility/>
<precipitation mode="no"/>
<weather number="803" value="broken clouds" icon="04d"/>
<lastupdate value="2016-09-11T18:08:01"/></current>

这是来自具有正确 api 密钥的开放天气的数据。我正在尝试仅解析城市、温度、压力和湿度。

这是天气片段

public class Weather_fragment extends Fragment {

    TextView cityField;
    TextView detailsField;
    TextView currentTemperatureField;

    Handler handler;

    public Weather_fragment(){
        handler = new Handler();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.weather_fragment, container, false);

        cityField = (TextView)rootView.findViewById(R.id.city_field);
        detailsField = (TextView)rootView.findViewById(R.id.details_field);
        currentTemperatureField = (TextView)rootView.findViewById(R.id.current_temperature_field);

        return rootView;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        updateWeatherData(new CityPreference(getActivity()).getCity());
    }

    private void updateWeatherData(final String city){
        new Thread(){
            public void run(){
                final JSONObject json = Fetch.getJSON(getActivity(), city);
                if(json == null){
                    handler.post(new Runnable(){
                        public void run(){
                            Toast.makeText(getActivity(),
                                getActivity().getString(R.string.place_not_found),
                                Toast.LENGTH_LONG).show();
                        }
                    });
                } else {
                    handler.post(new Runnable(){
                        public void run(){
                            renderWeather(json);
                        }
                    });
                }
            }
        }.start();
    }

    private void renderWeather(JSONObject json){
        try {

           cityField.setText(json.getString("name").toUpperCase(Locale.US));

            JSONObject main = json.getJSONObject("main");
            detailsField.setText("Humidity: " + main.getString("humidity") + "%" +
                "\n" + "Pressure: " + main.getString("pressure") + " hPa");

            currentTemperatureField.setText(String.format("%.2f", main.getDouble("temp"))+ " ℃");

        }catch(Exception e){
            Log.e("SimpleWeather", "error");
        }
    }


    public void changeCity(String city){
        updateWeatherData(city);
    }
}

这是 fetch java 类

public class Fetch {

    private static final String OPEN_WEATHER_MAP_API =
        "http://api.openweathermap.org/data/2.5/weather?q=";

    public static JSONObject getJSON(Context context, String city){
        try {

            String City = "Sydney, AU";
            URL url = new URL(String.format(OPEN_WEATHER_MAP_API, City));
            HttpURLConnection connection = (HttpURLConnection)url.openConnection();

            connection.addRequestProperty("x-api-key", context.getString(R.string.open_weather_maps_app_id));

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

            StringBuffer Weatherdata = new StringBuffer();
            String storage = "";
            while((storage=reader.readLine())!=null) {
                Weatherdata.append(storage  + "\n");
            }

            JSONObject data = new JSONObject(Weatherdata.toString());
            return data;
        } catch(Exception e) {
            return null;
        }
    }
}

【问题讨论】:

标签: android json


【解决方案1】:

您需要从 JSON 响应中去除 HTML,然后只有您能够检索 JSONArray,然后您可以解析它以获取数据。如下:

public String stripHtmlResponse (String html) {
    return Html.fromHtml(html).toString();
}

来源:How to strip HTML tags

然后按如下方式从 JSONArray 中检索数据

HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity); 
String noHTML = stripHtml(data);

JSONArray jsonArray = new JSONArray(noHTML);

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

    // Do parsing of your JSONArray for required data
}

【讨论】:

  • 所以在完成获取活动后,我发送给 renderweather 的 JSON 对象 json 需要去除 html。因为我会将这段代码与 renderweather 分开,对吗?
  • 您可以将 stripHtmlResponse 函数放在类中的任何位置。并在收到响应对象的任何地方使用检索 JSONArray 代码。
  • 我对这部分代码有点迷茫。 HttpEntity 实体 = response.getEntity();字符串数据 = EntityUtils.toString(entity);字符串 noHTML = stripHtml(data);这显示为未定义的变量,我将 JSONObject json 发送到 striphtmlresponse,目前它仍然异常。
  • 不确定这是否能回答问题...显示的数据甚至不是 JSON
  • 你回答了我的问题,我意识到我浪费了 3 个小时试图阅读甚至不是 json 的东西.....
【解决方案2】:

代码示例不是 JSON,而是 XML。但是,如果您想解析 JSON 字符串,我建议使用 GenSON。该库的存储库是 https://github.com/EvgeniGenchev/GenSON-lib 。在里面你可以找到用于解析 OpenWeather API 的示例 java 代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 2020-01-10
    相关资源
    最近更新 更多