I'm building an application on Android Studio that retrieves weather information in real time thanks to OpenWeatherMap and the API they offer.
The problem is, I'm using two phones with different SDKs. One is SDK 23 / Android 6.0 and the other is SDK 28 / Android 9.0.
Currently on the phone with SDK 23 I have no problem. However on the phone with SDK 28 I have a NullPointerException error. My second activity allows me to display information for city X and its weather information. So, finally the error I'm encountering on the phone with SDK 28 is this one :
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
I've looked into a lot of things to see where that could have come from, if it wasn't my AsyncTask or whatever, but I really don't see it.
Knowing that on the phone with the oldest version of Android it retrieves well the information from my editText that on the most recent version it doesn't retrieve it at all and the nullpointerException must come from there.
Do you know where this might be coming from?
Here is my AsyncTask :
public class ExecuteTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... strings) {
HttpURLConnection con = null ;
InputStream is = null;
try {
con = (HttpURLConnection) ( new URL(strings[0])).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;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
try {
String message = "";
String degre="";
String idMeteo="";
JSONObject jsonObject = new JSONObject(s);
String infoWeatherToday = jsonObject.getString("weather");
JSONObject WeatherTemperature = jsonObject.getJSONObject("main");
Integer deg = WeatherTemperature.getInt("temp");
deg = deg - 273;
JSONArray array = new JSONArray(infoWeatherToday);
int tablongueur=array.length();
for (int i = 0; i < tablongueur; i++) {
JSONObject jsonSecondary = array.getJSONObject(i);
String main = "";
//Integer id;
main = jsonSecondary.getString("main");
// id = jsonSecondary.getInt("id");
switch (main) {
case "Clouds":
main = "Nuageux";
PhotoMeteo.setImageResource(R.drawable.cloud);
break;
case "Clear":
main = "Ensoleillé";
PhotoMeteo.setImageResource(R.drawable.sun);
break;
case "Rain":
main = "Pluie";
PhotoMeteo.setImageResource(R.drawable.rain);
break;
case "Snow":
main = "Neige";
PhotoMeteo.setImageResource(R.drawable.snow);
break;
case "Smoke":
main = "Brouillard";
PhotoMeteo.setImageResource(R.drawable.smoke);
break;
case "Drizzle":
main = "Brumeux";
PhotoMeteo.setImageResource(R.drawable.drizzle);
break;
default:
main = "Météo introuvable !";
PhotoMeteo.setImageResource(R.drawable.ic_warning);
}
if (main != "" /*&& id != null*/) {
message += main + "\r\n";
degre += deg + "°C";
//idMeteo += "L'id de la météo est" + id;
}
}
if (message != "") {
resultWeather.setText(message);
resultDegre.setText(degre);
//resultIdMeteo.setText(idMeteo);
} else {
Toast.makeText(AccueilActivity.this, "Une erreur a eu lieu ", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
And here is the intent that I keep from my first activity called RegisterActivity to give it as a parameter for the "name" of the city
Intent intent = new Intent(RegisterActivity.this, AccueilActivity.class);
intent.putExtra(EXTRA_TEXT,cityField.getText().toString());
startActivity(intent);
In my 2nd activity called "AccueilActivity"
Intent intent = getIntent();
if(intent!=null)
{
textViewVille.setText(intent.getStringExtra(EXTRA_TEXT));
ville = intent.getStringExtra(EXTRA_TEXT);
FindWeather();
}
And my final function called FindWeather which execute the AsyncTask
public void FindWeather() {
cityToFind = ville;
try {
ExecuteTask tasky = new ExecuteTask();
tasky.execute("http://api.openweathermap.org/data/2.5/weather?q=" + cityToFind + "&APPID={MYAPKKEY}&LANG=fr&UNITS=metric");
} catch (Exception e) {
e.printStackTrace();
}
}
Just I don't give you the value of my APK Key because it isn't something interesting but the value is present in the initial code.
If I have a last things to add, ville is a simple TextView and cityToFind the value of my editText on the first activity.
If you need anything of my source code I can give you more.
Thank you.