I am trying to write a network functionality for an android application with android studio. It is very simple. I just try to post some data to an url and fetch data back (all in simple HTTP). I am testing with the emulator, device is Pixel 2 API 28.
As long as the internet is activated on the emulator everything works fine. But as soon as i disable the wifi, the application hangs when I try to send the data, and finally crashes. Android offers to stop the application.
It hangs on this call:
urlConnection.getOutputStream().write(postDataBytes);
Documentation and web say, that this method should throw an exception, when there is no internet connection. Especially the UnknownHostException is mentioned very often. But I do not receive any exception.
Where could I go from here?
Here is the code of the whole connection class i use. The doInBackground method is the place where the internet magic happens and the error occures:
package com.example.tf2;
//This class is used for easier networking.
//It is using volley..
import android.content.Context;
/* import android.graphics.Bitmap; */
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
/* Info about "associative arrays" for the post params taken from Stackoverflow:
https://stackoverflow.com/questions/5122913/java-associative-array
*/
public class mvNetConnect extends AsyncTask<String, Void, String> {
private final String endpoint = "*** here is a valid url ***";
Map<String, String> post_params = new HashMap<String, String>();
String mode = "GET";
String token = "";
private Context useContext;
public mvNetConnect(Context myContext) {
useContext = myContext;
}
@Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection;
try {
//Daten aus Eingabefeldern auslesen.
//TextView textview_username =
url = new URL(endpoint + urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(1000); // Timeout in Millisekunden. Ansonsten bekommt der Enduser nie eine Antwort..
urlConnection.setReadTimeout(1000);
//Falls wir ein Token haben, fügen wir es dem Request hinzu..
if(token != "") {
urlConnection.addRequestProperty("auth", token);
}
//Falls dies ein Post-Aufruf ist, machen wir auch einen daraus..
StringBuilder postData = new StringBuilder();
if(mode == "POST") {
urlConnection.setRequestMethod("POST");
//Post Parameter hinzufügen (Loop taken from stackoverflow (Thread from harto): https://stackoverflow.com/questions/1066589/iterate-through-a-hashmap)
for (Map.Entry<String, String> entry : post_params.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// Add Params to request..
if (postData.length() != 0) {
postData.append('&');
}
postData.append(URLEncoder.encode(key, "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(value, "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
urlConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
urlConnection.setDoOutput(true);
urlConnection.getOutputStream().write(postDataBytes);
}
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read(); //Erstes Zeichen lesen.
while(data != -1) { //So lang es Daten gibt.
char current = (char) data; //Zeichen umwandeln.
result += current; //Zeichen an Ausgabe anhängen.
data = reader.read(); //Nächstes Zeichen lesen.
}
} catch(UnknownHostException e) {
Log.i("Info", "error!!!");
} catch(MalformedURLException e) {
Log.i("Info", "no error?");
e.printStackTrace();
return "Failed";
} catch(Exception e) {
Log.i("Info", "errors..");
e.printStackTrace();
return "Failed";
} catch (Throwable throwable) {
// Output unexpected Throwables.
Log.i("info", throwable.toString());
}
Log.i("Info", result.toString());
return result;
}
public void setModeToPost() {
mode = "POST";
}
public void setModeToGet() {
mode = "GET";
}
public void setToken(String _token) {
token = _token;
}
public void addPostParam(String key, String value) {
post_params.put(key, value);
//To extract a key one could use: post_params.get(key);
}
public void clearPostParams(String key, String value) {
post_params.clear();
}
}