应用程序从OpenWeatherMap API获取数据,并在我指示城市时正常工作,例如“伦敦”。用变量“place”替换“London”时出错。。在下面可以找到代码。
有人能帮我吗?
**MAIN ACTIVITY**
public class MainActivity extends AppCompatActivity {
//create the fields on the Activity
private TextView cityName;
private TextView temp;
private TextView description;
private TextView humidity;
private TextView pressure;
private TextView wind;
private TextView sunrise;
private TextView sunset;
private TextView updated;
private Exception error;
Weather weather = new Weather();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set up all the resources for the Views here
cityName = (TextView)findViewById(R.id.cityText);
temp = (TextView)findViewById(R.id.tempText);
description = (TextView)findViewById(R.id.CloudText);
humidity = (TextView)findViewById(R.id.HumidText);
pressure = (TextView)findViewById(R.id.PressureText);
wind = (TextView)findViewById(R.id.WindText);
sunrise = (TextView)findViewById(R.id.RiseText);
sunset = (TextView)findViewById(R.id.SetText);
updated = (TextView)findViewById(R.id.UpdateText);
//instantiate a CityPreference object from the MainActivity that
carries the city with it..
//render the data based on the city you get through the parsing
CityPreference cityPreference = new CityPreference(MainActivity.this);
renderWeatherData(cityPreference.getCity());
}
public void renderWeatherData (String city){
// we want to do all of our tasks in the background, use AsyncTask for this
WeatherTask weatherTask = new WeatherTask();
weatherTask.execute(new String[]{city} + "&units=metric");
}
//last parameter is Weather, this is what we will be populating
private class WeatherTask extends AsyncTask<String, Void, Weather>{
//AsyncTask <PARAMETERS, TASK, RESULT>
@Override
protected Weather doInBackground(String... params) {
//background computation
//data variable holds all the data that we have got..
//instantiate the weather client and get the weather data..
//getWeatherData gets all necessary data from HTTPClient
//getWeather parses all the data from the JSONParser
try {
String data = ((new WeatherHTTPClient().getWeatherData(params[0])));
weather = JSONWeatherParser.getWeather(data);
//create a log to test if everything is working
Log.v("Data:",weather.currentCondition.getDescription());
return weather;
} catch (Exception e) {
error = e;
}
return null;
}
//here you will populate the data so you can show it to the user
@Override
protected void onPostExecute(Weather weather) {
super.onPostExecute(weather);
try {
//gets time and decimal formats and applies it to the data underneath
DateFormat df = DateFormat.getTimeInstance();
String sunriseDate = df.format(new Date(Weather.place.getSunrise()));
String sunsetDate = df.format(new Date(Weather.place.getSunset()));
String updateDate = df.format(new Date(Weather.place.getLastupdate()));
DecimalFormat decimalFormat = new DecimalFormat("#.#");
String tempFormat = decimalFormat.format(weather.currentCondition.getTemperature());
//gets the value from the JSON and parses it in the view of the activity
cityName.setText(weather.place.getCity() + "," + weather.place.getCountry());
temp.setText("" + tempFormat + "C");
humidity.setText("Humidity" + weather.currentCondition.getHumidity() + "%");
pressure.setText("Pressure" + weather.currentCondition.getPressure() + "hPa");
wind.setText("Wind" + weather.wind.getSpeed() + "mps");
sunrise.setText("Sunrise" + sunriseDate);
sunset.setText("Sunset" + sunsetDate);
updated.setText("Updated" + updateDate);
description.setText("Condition" + weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescription() + ")");
} catch(Exception e) {
error = e;
}
}
}
//create an alert dialog to put in the city you want to parse the data for - A subclass of Dialog that can display one, two or three buttons.
private void showInputDialog () {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Change City");
final EditText cityInput = new EditText(MainActivity.this);
cityInput.setInputType(InputType.TYPE_CLASS_TEXT);
cityInput.setHint("put down city name");
builder.setView(cityInput);
builder.setPositiveButton("Submit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which){
CityPreference cityPreference = new CityPreference(MainActivity.this);
cityPreference.setCity(cityInput.getText().toString());
String newCity = cityPreference.getCity();
renderWeatherData(newCity);
}
});
builder.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//inflate the menu, this adds items to the action bar if it is present
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.change_cityId){
showInputDialog();
}
return super.onOptionsItemSelected(item);
}
}
**HTTP CLIENT**
public class WeatherHTTPClient {
public String getWeatherData (String place) throws IOException {
// setting things up.., create connection between application and the web, everything we get from the web comes as an inputstream
HttpURLConnection connection = null;
InputStream inputStream = null;
// api.openweathermap.org/data/2.5/weather?q=London
// errors may occur when you connect to the internet, build this in the model with try...catch
在下一个语句中,当我将“place”替换为“London”时,应用程序就可以运行了。这部分一定有错误,但我找不到。。我需要帮助。。
try {
connection = (HttpURLConnection) (new URL(Utils.BASE_URL + place +"&APPID=f77c39703fb6be71e2c5a96e58edc077")).openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
//read the response, buffer "bucket" where you are going to put your data
StringBuffer stringBuffer = new StringBuffer();
//you get a stream of bits and data to your device - everything comes in as an inputstream
inputStream = connection.getInputStream();
//BufferedReader is the only thing that can read the stream of data - hold it and start reading
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
//line is set as the data read by the BufferedReader, Stringbuffer reads the Buffer and goes to the next one
while ((line = bufferedReader.readLine()) != null){
stringBuffer.append(line + "\r\n");
}
inputStream.close();
connection.disconnect();
return stringBuffer.toString();
} catch (IOException e) {e.printStackTrace();}
return null;
}
}
**WEATHER DATA MODEL JSON**
public class Weather {
public static Place place;
public String IconData;
public CurrentCondition currentCondition = new CurrentCondition();
public Temperature temperature = new Temperature();
public Wind wind = new Wind();
public Snow snow = new Snow();
public Clouds clouds = new Clouds();
}
**PLACE DATA MODEL, left out getters and setters**
**LEFT OUT THE FULL DATA MODEL**
public class Place {
private float lon ;
private float lat ;
private long sunset;
private long sunrise;
private String country;
private String city;
private long lastupdate;
**THE WEATHER PARSER**
public class JSONWeatherParser {
public static Weather getWeather(String data){
//we call the top JSON object weather
Weather weather = new Weather();
//create JSONObject that holds all of the data you get from the web
//place is the parameter you use to get all the data for
//the rest of the variables you have to "calculate" from your data model
//tagName needs to be EXACTLY as it is in the JSON
try {
JSONObject jsonObject = new JSONObject(data);
Place place = new Place();
//for each "header" in JSON you create a JSONObject or a JSONArray
JSONObject coorObj = Utils.getObject("coord", jsonObject);
//you set the latitude by getting the "lat" variable from the coorObj from the top JSON Object weather
place.setLat(Utils.getFloat("lat",coorObj));
place.setLon(Utils.getFloat("lon",coorObj));
//get the sys object
JSONObject sysObj = Utils.getObject("sys", jsonObject);
place.setCountry(Utils.getString("country", sysObj));
//dt Lastupdate is found directly under the jsonObject, hence ...
place.setLastupdate(Utils.getInt("dt", jsonObject));
place.setSunrise(Utils.getInt("sunrise",sysObj));
place.setSunset(Utils.getInt("sunset",sysObj));
place.setCity(Utils.getString("name",jsonObject));
weather.place = place;
//get the weather info, it is a JSONArray of the main jsonObject (the whole thing) - starts with square brackets
JSONArray jsonArray = jsonObject.getJSONArray("weather");
//get the underlying Jsonobject from the jsonarray
JSONObject jsonWeather = jsonArray.getJSONObject(0);
weather.currentCondition.setWeatherId(Utils.getInt("id",jsonWeather));
weather.currentCondition.setDescription(Utils.getString("description", jsonWeather));
weather.currentCondition.setCondition(Utils.getString("main",jsonWeather));
weather.currentCondition.setIcon(Utils.getString("icon",jsonWeather));
JSONObject mainObj = Utils.getObject("main", jsonObject);
weather.currentCondition.setHumidity(Utils.getInt("humidity",mainObj));
weather.currentCondition.setPressure(Utils.getInt("pressure",mainObj));
weather.currentCondition.setMin_temp(Utils.getFloat("temp_min",mainObj));
weather.currentCondition.setMax_temp(Utils.getFloat("temp_max", mainObj));
weather.currentCondition.setTemperature(Utils.getDouble("temp",mainObj));
JSONObject windObj = Utils.getObject("wind", jsonObject);
weather.wind.setSpeed(Utils.getFloat("speed", windObj));
weather.wind.setDeg(Utils.getFloat("deg",windObj));
JSONObject cloudObj = Utils.getObject("clouds", jsonObject);
weather.clouds.setPrecipitation(Utils.getInt("all", cloudObj));
return weather;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}