I am trying to learn Android Async and json data parsing. I am using openweathermap.org API for displaying current weather for a place user type. My application displayed it However, it is not flexible as it is displaying all different details such as weather description, latitude, longitude, Wind Speed , current temperature.. all in a single string so it is not reusable which we should make. Suppose if i want to display the place on google map with current temperature with a map marker, I should be able to get only what i want in this case current temperature and latitude and longitude. I want these details to display on separate textfields. I am beginner in Android. Please look into my code and suggest me with a solution and guidance.
Here is my 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;
}
}
Main Activity
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();
}
}
}
This code runs and output current weather but its not reusuable because everything is concatenated to single string.
To make it reusable and easy to access to each attribute as you want, how about making a class Weather
that contains those attribute and when you start parsing the json, make an instance of it and write them there.
For example, instead of just this:
String lon = jsonHelperGetString(coord, "lon");
String lat = jsonHelperGetString(coord, "lat");
jsonResult += "Lon: " + lon + "\n";
jsonResult += "Lat: " + lat + "\n";
...
change to sth like:
Weather aWeather = new Weather();
String lon = jsonHelperGetString(coord, "lon");
String lat = jsonHelperGetString(coord, "lat");
aWeather.lon = long;
aWeather.lat = lat;
...
return aWeather;
Remember to change return type onPostExcute(String string) into onPostExcute(Weather weather);
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.