openWeatherMap APIを使用して、緯度、経度を使用して現在の天気を取得するAndroidアプリケーションを作成しています。Aysnctask を使用して天気を取得しましたが、アプリケーションがクラッシュし、nullPointerException が発生します。
aysnctask:
private class JSONWeatherTask extends AsyncTask<String, Void, Weather> {
@Override
protected Weather doInBackground(String... params) {
Weather weather = new Weather();
// String data = ( (new WeatherHttpClient()).getWeatherData(params[0]));
String data = ( (new WeatherHttpClient()).getWeatherData(params[0],params[1]));
try {
weather = JSONWeatherParser.getWeather(data);
// Let's retrieve the icon
weather.iconData = ( (new WeatherHttpClient()).getImage(weather.currentCondition.getIcon()));
} catch (JSONException e) {
e.printStackTrace();
}
return weather;
}
@Override
protected void onPostExecute(Weather weather) {
super.onPostExecute(weather);
if (weather.iconData != null && weather.iconData.length > 0) {
Bitmap img = BitmapFactory.decodeByteArray(weather.iconData, 0, weather.iconData.length);
imgView.setImageBitmap(img);
}
condDescr.setText(weather.currentCondition.getCondition() + "(" + weather.currentCondition.getDescr() + ")");
temp.setText("" + Math.round((weather.temperature.getTemp() - 275.15)) + "°C");
hum.setText("" + weather.currentCondition.getHumidity() + "%");
press.setText("" + weather.currentCondition.getPressure() + " hPa");
windSpeed.setText("" + weather.wind.getSpeed() + " mps");
windDeg.setText("" + weather.wind.getDeg() + "°");
}
}
doInBackground メソッドのパラメータは、現在の緯度、経度である必要があります。aysnktask を次のように呼び出します。
JSONWeatherTask task = new JSONWeatherTask();
task.execute(new String[]{currentLatitude,currentLongitude});
そして、次のように openWeatherMap に接続します。
public String getWeatherData(String lat,String lng) {
HttpURLConnection con = null ;
InputStream is = null;
try {
con=(HttpURLConnection)(new URL("http://api.openweathermap.org/data/2.5/weather?lat=%"+Double.parseDouble(lat)+"&lon="+Double.parseDouble(lng))).openConnection();
con.setRequestMethod("GET");
con.setDoInput(true);
con.setDoOutput(true);
con.connect();
// Let's read the response
StringBuffer buffer = new StringBuffer();
is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ( (line = br.readLine()) != null )
buffer.append(line + "\r\n");
is.close();
con.disconnect();
return buffer.toString();
}
catch(Throwable t) {
t.printStackTrace();
}
finally {
try { is.close(); } catch(Throwable t) {}
try { con.disconnect(); } catch(Throwable t) {}
}
return null;
}
nullPointerException は次の行にあります。
weather = JSONWeatherParser.getWeather(data);
ここにlogCatがあります:
12-03 11:34:29.110: E/AndroidRuntime(16271): FATAL EXCEPTION: AsyncTask #1
12-03 11:34:29.110: E/AndroidRuntime(16271): java.lang.RuntimeException: An error occured while executing doInBackground()
12-03 11:34:29.110: E/AndroidRuntime(16271): at android.os.AsyncTask$3.done(AsyncTask.java:299)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-03 11:34:29.110: E/AndroidRuntime(16271): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.lang.Thread.run(Thread.java:856)
12-03 11:34:29.110: E/AndroidRuntime(16271): Caused by: java.lang.NullPointerException
12-03 11:34:29.110: E/AndroidRuntime(16271): at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
12-03 11:34:29.110: E/AndroidRuntime(16271): at org.json.JSONTokener.nextValue(JSONTokener.java:94)
12-03 11:34:29.110: E/AndroidRuntime(16271): at org.json.JSONObject.<init>(JSONObject.java:154)
12-03 11:34:29.110: E/AndroidRuntime(16271): at org.json.JSONObject.<init>(JSONObject.java:171)
12-03 11:34:29.110: E/AndroidRuntime(16271): at com.survivingwithandroid.weatherapp.JSONWeatherParser.getWeather(JSONWeatherParser.java:42)
12-03 11:34:29.110: E/AndroidRuntime(16271): at com.survivingwithandroid.weatherapp.MainActivity$JSONWeatherTask.doInBackground(MainActivity.java:290)
12-03 11:34:29.110: E/AndroidRuntime(16271): at com.survivingwithandroid.weatherapp.MainActivity$JSONWeatherTask.doInBackground(MainActivity.java:1)
12-03 11:34:29.110: E/AndroidRuntime(16271): at android.os.AsyncTask$2.call(AsyncTask.java:287)
12-03 11:34:29.110: E/AndroidRuntime(16271): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
これは getWeather メソッドです:
public static Weather getWeather(String data) throws JSONException {
Weather weather = new Weather();
// We create out JSONObject from the data
JSONObject jObj = new JSONObject(data);
// We start extracting the info
Location1 loc = new Location1();
JSONObject coordObj = getObject("coord", jObj);
loc.setLatitude(getFloat("lat", coordObj));
loc.setLongitude(getFloat("lon", coordObj));
JSONObject sysObj = getObject("sys", jObj);
loc.setCountry(getString("country", sysObj));
loc.setSunrise(getInt("sunrise", sysObj));
loc.setSunset(getInt("sunset", sysObj));
loc.setCity(getString("name", jObj));
weather.location = loc;
// We get weather info (This is an array)
JSONArray jArr = jObj.getJSONArray("weather");
// We use only the first value
JSONObject JSONWeather = jArr.getJSONObject(0);
weather.currentCondition.setWeatherId(getInt("id", JSONWeather));
weather.currentCondition.setDescr(getString("description", JSONWeather));
weather.currentCondition.setCondition(getString("main", JSONWeather));
weather.currentCondition.setIcon(getString("icon", JSONWeather));
JSONObject mainObj = getObject("main", jObj);
weather.currentCondition.setHumidity(getInt("humidity", mainObj));
weather.currentCondition.setPressure(getInt("pressure", mainObj));
weather.temperature.setMaxTemp(getFloat("temp_max", mainObj));
weather.temperature.setMinTemp(getFloat("temp_min", mainObj));
weather.temperature.setTemp(getFloat("temp", mainObj));
// Wind
JSONObject wObj = getObject("wind", jObj);
weather.wind.setSpeed(getFloat("speed", wObj));
weather.wind.setDeg(getFloat("deg", wObj));
// Clouds
JSONObject cObj = getObject("clouds", jObj);
weather.clouds.setPerc(getInt("all", cObj));
// We download the icon to show
return weather;
}