我正在尝试学习Android Async和json数据解析。我使用openweathermap.org API显示地方用户类型的当前天气。我的应用程序显示它然而,它不灵活,因为它显示所有不同的细节,如天气描述,纬度,经度,风速,当前温度......所有都在一个字符串中,因此它不可重复使用我们应该。假设我想在谷歌地图上显示具有当前温度的地图标记,我应该只能获得我想要的当前温度和纬度和经度。 我希望这些细节显示在单独的文本字段中。我是Android的初学者。请查看我的代码,并向我提出解决方案和指导。
这是我的JSONWeatherData.java
public class JSONWeatherData {
public static String getData(String weatherJson) throws JSONException {
String jsonResult = "";
try {
JSONObject JsonObject = new JSONObject(weatherJson);
String cod = jsonHelperGetString(JsonObject, "cod");
if(cod != null) {
if (cod.equals("200")) {
jsonResult += jsonHelperGetString(JsonObject, "name") + "\n";
JSONObject sys = jsonHelperGetJSONObject(JsonObject, "sys");
if (sys != null) {
jsonResult += jsonHelperGetString(sys, "country") + "\n";
}
jsonResult += "\n";
JSONObject coord = jsonHelperGetJSONObject(JsonObject, "coord");
if(coord != null){
String lon = jsonHelperGetString(coord, "lon");
String lat = jsonHelperGetString(coord, "lat");
jsonResult += "Lon: " + lon + "\n";
jsonResult += "Lat: " + lat + "\n";
}
jsonResult += "\n";
JSONArray weather = jsonHelperGetJSONArray(JsonObject, "weather");
if(weather != null){
for(int i=0; i<weather.length(); i++){
JSONObject thisWeather = weather.getJSONObject(i);
jsonResult += "Weather " + i + ":\n";
jsonResult += jsonHelperGetString(thisWeather, "main") + "\n";
jsonResult += jsonHelperGetString(thisWeather, "description") + "\n";
jsonResult += "\n";
}
}
JSONObject main = jsonHelperGetJSONObject(JsonObject, "main");
if(main != null){
jsonResult += "temp: " + jsonHelperGetString(main, "temp") + "\n";
jsonResult += "\n";
}
JSONObject wind = jsonHelperGetJSONObject(JsonObject, "wind");
if(wind != null){
jsonResult += "Wind Speed: " + jsonHelperGetString(wind, "speed") + "\n";
jsonResult += "\n";
}
}
else if(cod.equals("404")){
String message = jsonHelperGetString(JsonObject, "message");
jsonResult += "cod 404: " + message;
}
} else{
jsonResult += "cod == null\n";
}
} catch (JSONException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage(), e);
jsonResult += e.getMessage();
}
return jsonResult;
}
private static String jsonHelperGetString(JSONObject obj, String k){
String v = null;
try {
v = obj.getString(k);
} catch (JSONException e) {
e.printStackTrace();
}
return v;
}
private static JSONObject jsonHelperGetJSONObject(JSONObject obj, String k){
JSONObject o = null;
try {
o = obj.getJSONObject(k);
} catch (JSONException e) {
e.printStackTrace();
}
return o;
}
private static JSONArray jsonHelperGetJSONArray(JSONObject obj, String k){
JSONArray a = null;
try {
a = obj.getJSONArray(k);
} catch (JSONException e) {
e.printStackTrace();
}
return a;
}
}
主要活动
Public class MainActivity extends Activity {
Button btnSubmitCity, btnMap;
EditText editCityText;
TextView weather_description, current_temp, wind_speed, textViewResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editCityText = (EditText) findViewById(R.id.editCity);
btnMap =(Button) findViewById(R.id.mapButton);
btnSubmitCity = (Button) findViewById(R.id.submitCity);
weather_description = (TextView) findViewById(R.id.weatherDescription);
current_temp = (TextView) findViewById(R.id.currentTemp);
wind_speed = (TextView) findViewById(R.id.windSpeed);
//textViewResult = (TextView)findViewById(R.id.result);
textViewResult = (TextView)findViewById(R.id.result);
btnMap.setVisibility(View.INVISIBLE);
btnMap.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
btnSubmitCity.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//editCityText.getText().toString();
//HttpGetTask
String cityString = editCityText.getText().toString();
if(TextUtils.isEmpty(cityString)) {
Toast.makeText(MainActivity.this, "Enter a place", Toast.LENGTH_LONG).show();
return;
} else{
new HttpGetTask(cityString, weather_description).execute(cityString);
btnMap.setVisibility(View.VISIBLE);
}
//String cityString = city.getText().toString();
//new HttpGetTask().execute();
/*
new HttpGetTask(
editCityText.getText().toString(),
textViewResult).execute();
*/
}
});
}
private class HttpGetTask extends AsyncTask<String, Void, String> {
final String FORECAST_BASE_URL = "http://api.openweathermap.org/data/2.5/weather?";
private static final String TAG = "HttpGetTask";
String cityName;
TextView tvResult;
HttpGetTask(String cityName, TextView tvResult){
this.cityName = cityName;
this.tvResult = tvResult;
}
@Override
protected String doInBackground(String... params){
InputStream in = null;
HttpURLConnection httpUrlConnection = null;
String result = "";
try {
Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
.appendQueryParameter("q", cityName+",us") // city
.appendQueryParameter("mode", "json") // json format as result
.appendQueryParameter("units", "imperial") // metric unit
.appendQueryParameter("APPID", "Replace with your openweathermap API ID")
.build();
URL url = new URL(builtUri.toString());
httpUrlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(
httpUrlConnection.getInputStream());
String data = readStream(in);
result = edu.uco.rawal.p6rabina.JSONWeatherData.getData(data);
} catch (MalformedURLException exception) {
Log.e(TAG, "MalformedURLException");
} catch (IOException exception) {
Log.e(TAG, "IOException");
} catch (JSONException e) {
Log.e(TAG, e.getMessage(), e);
e.printStackTrace();
} finally {
if (null != httpUrlConnection) {
httpUrlConnection.disconnect();
}
if (in != null) {
try {
in.close();
} catch (final IOException e) {
Log.e(TAG, "Error closing stream", e);
}
}
}
return result;
}
@Override
protected void onPostExecute(String result) {
if (result == null || result == "") {
Toast.makeText(MainActivity.this,
"Invalid weather data. Possibly a wrong query",
Toast.LENGTH_SHORT).show();
return;
} else {
//btnMap.setVisibility(View.VISIBLE);
tvResult.setText(result);
}
}
private String readStream(InputStream in) {
BufferedReader reader = null;
StringBuffer data = new StringBuffer("");
try {
reader = new BufferedReader(new InputStreamReader(in));
String line ;
while ((line = reader.readLine()) != null) {
data.append(line);
}
} catch (IOException e) {
Log.e(TAG, "IOException");
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return data.toString();
}
}
}
此代码运行并输出当前天气但不可重复使用,因为所有内容都连接到单个字符串。
答案 0 :(得分:2)
为了使其可重用且易于访问每个属性,如何创建包含这些属性的类Weather
,以及何时开始解析json,创建它的实例并将其写入其中。
例如,而不仅仅是这个:
String lon = jsonHelperGetString(coord, "lon");
String lat = jsonHelperGetString(coord, "lat");
jsonResult += "Lon: " + lon + "\n";
jsonResult += "Lat: " + lat + "\n";
...
改为......:
Weather aWeather = new Weather();
String lon = jsonHelperGetString(coord, "lon");
String lat = jsonHelperGetString(coord, "lat");
aWeather.lon = long;
aWeather.lat = lat;
...
return aWeather;
请记住将onPostExcute(String string)的返回类型更改为onPostExcute(天气天气);