jacmurphy50
jacmurphy50

Reputation: 95

Unknown Host Exception using emulator and HttpURLConnection

I'm currently in the final stages of developing my Android application on Android studio. Built the APK files to run them on a device seperate to one of the Android studio emulators. I went with Andy android emulator. I installed the APK but when I tried to log in i.e. connect to the server I got an unknown host exception as follows:

System.err: java.net.UnknownHostException: http://point_collector.netau.net/FetchData.php
System.err:     at libcore.net.http.HttpConnection$Address.<init>(HttpConnection.java:282)
System.err:     at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
System.err:     at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
System.err:     at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
System.err:     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
System.err:     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
System.err:     at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81)
System.err:     at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:197)
System.err:     at com.jack.pointcollector.ServerRequests$GetDataAsyncTask.doInBackground(ServerRequests.java:169)
System.err:     at com.jack.pointcollector.ServerRequests$GetDataAsyncTask.doInBackground(ServerRequests.java:132)
com.jack.pointcollector W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:287)
com.jack.pointcollector W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
com.jack.pointcollector W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
System.err:     at java.lang.Thread.run(Thread.java:856)

The server request code is as follows:

public class ServerRequests {

    //Variables for this class
    //Process Dialog informs the user what is happening while thier request is being carried out
    //Connection timeout will be the time in milliseconds of how long the connection will last
    //Server address is the location of the PHP files
    ProgressDialog progressDialog;
    public static final int CONNECTION_TIMEOUT = 1000 * 15;
    public static final String SERVER_ADDRESS = "http://point_collector.netau.net/";


    public ServerRequests(Context context) {
        //process dialog requires the context of the class e.g. Register.this or Login.this
        progressDialog = new ProgressDialog(context);
        progressDialog.setCancelable(false);
        progressDialog.setTitle("Processing");
        progressDialog.setMessage("Please wait...");
    }
    public void storeUserData(User user, GetUserCallBack callBack) {
        //Process to write to the database to be performed in the background
        progressDialog.show();
        new StoreDataAsyncTask(user, callBack).execute();
    }
    public void fetchUserData(User user, GetUserCallBack callBack) {
        //Process to read from the database to be performed in the background
        progressDialog.show();
        new GetDataAsyncTask(user,callBack).execute();
    }


    public void storeChoreData(Chore chore, GetUserCallBack callBack){
        progressDialog.show();
        new StoreChoreAsyncTask(chore, callBack).execute();
    }

    public void storeRewardData(Reward reward, GetUserCallBack callBack){
        progressDialog.show();
        new StoreRewardAsyncTask(reward, callBack).execute();
    }

    //Creates a background thread to write to the data base
    public class StoreDataAsyncTask extends AsyncTask<Void, Void, Void> {
        //instance variables one for a user
        //GetUserCallBack is an interface which signals when the operation has been completed
        User user;
        GetUserCallBack userCallBack;

        public StoreDataAsyncTask(User user0, GetUserCallBack callBack0) {
            user = user0;
            userCallBack = callBack0;
        }
        @Override
        protected Void doInBackground(Void... params) {
            try {
                //The URL to be connected
                //Then we open the connection
                //Set the conditions the connection must follow
                URL url = new URL(SERVER_ADDRESS + "Register.php");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(CONNECTION_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                //Identifies the objects to be passed for the PHP files
                Uri.Builder builder = new Uri.Builder()
                        .appendQueryParameter("username", user.username)
                        .appendQueryParameter("password", user.password)
                        .appendQueryParameter("email", user.email);
                //Determines whether the user is creating a parent or child account
                if(user.isParent) builder.appendQueryParameter("userType", "Parent");
                else builder.appendQueryParameter("userType", "Child");

                //Encodes the data for the PHP file
                String query = builder.build().getEncodedQuery();

                //Records entry
                Log.d("query", query);

                //Creates an output to send out the query
                //Then flushes the writer and closes all outputs
                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
                writer.write(query);
                writer.flush();
                writer.close();
                os.close();
                //Gets the response code to ensure this was succesful.
                int code = conn.getResponseCode();
                Log.d("code", Integer.toString(code));
                conn.connect();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            //After the previous method executes we end the process dialog
            //and we return the user call back
            progressDialog.dismiss();
            userCallBack.complete(null);
            super.onPostExecute(aVoid);
        }
    }

    public class GetDataAsyncTask extends AsyncTask<Void, Void, User> {
        //instance variables one for a user
        //GetUserCallBack is an interface which signals when the operation has been completed
        User user;
        GetUserCallBack userCallBack;

        public GetDataAsyncTask(User user0, GetUserCallBack callBack0) {
            user = user0;
            userCallBack = callBack0;
        }
        @Override
        protected User doInBackground(Void... params) {
            //A HashMap to determine what we want to retrieve from the server
            //The URL is the location of the PHP file to validate a user
            HashMap<String, String> param = new HashMap<>();
            String requestURL = SERVER_ADDRESS+"FetchData.php";
            param.put("username", user.username);
            param.put("password", user.password);
            //Checks if a the user logging in is a parent or child
            if(user.isParent) param.put("userType", "Parent");
            else param.put("userType", "Child");

            URL url;
            User returnedUser = null;
            try {
                //Opens the connection to the PHP files
                //Sets the conditions of the connection
                url = new URL(requestURL);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(CONNECTION_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                //Opens an output stream to send the data to be verified
                // and then closes the all output streams and flushes the output writer
                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
                writer.write(getPostDataString(param));
                writer.flush();
                writer.close();
                os.close();
                //saves the response code to ensure connection was succesful
                int code = conn.getResponseCode();
                Log.d("code", Integer.toString(code));

                //Opens an input stream to retrieve verified data back from the server
                //Starts a String Builder to read the data off the input
                //Closes the BufferedReader once it has finished building the string
                InputStream responseStream = new BufferedInputStream(conn.getInputStream());
                BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
                String line;
                StringBuilder stringBuilder = new StringBuilder();
                while ((line = responseStreamReader.readLine()) != null) { stringBuilder.append(line);}
                responseStreamReader.close();

                String response = stringBuilder.toString();
                Log.d("response", response);
                if(response.contains("This is a parent")) {
                    user.isParent = true;
                }
                else user.isChild = true;



                //Creates a JSON object from the string
                JSONObject jsonResponse = new JSONObject(response);
                Log.d("length",Integer.toString(jsonResponse.length()));
                //Stores the verified user details if the response is not 0
                if(jsonResponse.length() > 0) {
                    if(user.isChild) {
                        int flag = jsonResponse.getInt("request_flag");
                        returnedUser = new User(user.username, user.password, flag);
                        Log.d("returned user", returnedUser.username);
                    }
                    else {
                        returnedUser = new User(user.username, user.password);
                        Log.d("returned user", returnedUser.username);

                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return returnedUser;
        }
        private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
            //Correctly formats the data to be sent to the PHP file
            StringBuilder result = new StringBuilder();
            boolean first = true;
            for (Map.Entry<String, String> entry : params.entrySet()) {
                if (first) first = false;
                else result.append("&");
                result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
                result.append("=");
                result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
            }
            return result.toString();
        }
        @Override
        protected void onPostExecute(User returnedUser) {
            //After the previous method executes we end the process dialog
            //and we return the user call back and return the verified user
            progressDialog.dismiss();
            userCallBack.complete(returnedUser);
            super.onPostExecute(returnedUser);
        }
    }

    public class StoreChoreAsyncTask extends AsyncTask<Void, Void, Void> {
        //instance variables one for a chore
        //GetUserCallBack is an interface which signals when the operation has been completed
        Chore chore;
        GetUserCallBack userCallBack;

        public StoreChoreAsyncTask(Chore chore0, GetUserCallBack callBack0) {
            chore = chore0;
            userCallBack = callBack0;
        }
        @Override
        protected Void doInBackground(Void... params) {
            try {
                //The URL to be connected
                //Then we open the connection
                //Set the conditions the connection must follow
                URL url = new URL(SERVER_ADDRESS + "Chore.php");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(CONNECTION_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                //Identifies the objects to be passed for the PHP files
                Uri.Builder builder = new Uri.Builder()
                        .appendQueryParameter("chore", chore.chore)
                        .appendQueryParameter("points", chore.points +"")
                        .appendQueryParameter("parent_name", chore.pname);


                //Encodes the data for the PHP file
                String query = builder.build().getEncodedQuery();

                //Records entry
                Log.d("query", query);

                //Creates an output to send out the query
                //Then flushes the writer and closes all outputs
                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
                writer.write(query);
                writer.flush();
                writer.close();
                os.close();
                //Gets the response code to ensure this was succesful.
                int code = conn.getResponseCode();
                Log.d("code", Integer.toString(code));
                conn.connect();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            //After the previous method executes we end the process dialog
            //and we return the user call back
            progressDialog.dismiss();
            userCallBack.complete(null);
            super.onPostExecute(aVoid);
        }
    }

    public class StoreRewardAsyncTask extends AsyncTask<Void, Void, Void> {
        //instance variables one for a reward
        //GetUserCallBack is an interface which signals when the operation has been completed
        Reward reward;
        GetUserCallBack userCallBack;

        public StoreRewardAsyncTask(Reward reward0, GetUserCallBack callBack0) {
            reward = reward0;
            userCallBack = callBack0;
        }
        @Override
        protected Void doInBackground(Void... params) {
            try {
                //The URL to be connected
                //Then we open the connection
                //Set the conditions the connection must follow
                URL url = new URL(SERVER_ADDRESS + "Reward.php");
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(CONNECTION_TIMEOUT);
                conn.setConnectTimeout(CONNECTION_TIMEOUT);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                //Identifies the objects to be passed for the PHP files
                Uri.Builder builder = new Uri.Builder()
                        .appendQueryParameter("reward", reward.reward)
                        .appendQueryParameter("child", reward.child)
                        .appendQueryParameter("points", reward.points +"")
                        .appendQueryParameter("parent", reward.pname);


                //Encodes the data for the PHP file
                String query = builder.build().getEncodedQuery();

                //Records entry
                Log.d("query", query);

                //Creates an output to send out the query
                //Then flushes the writer and closes all outputs
                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
                writer.write(query);
                writer.flush();
                writer.close();
                os.close();
                //Gets the response code to ensure this was succesful.
                int code = conn.getResponseCode();
                Log.d("code", Integer.toString(code));
                conn.connect();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
        @Override
        protected void onPostExecute(Void aVoid) {
            //After the previous method executes we end the process dialog
            //and we return the user call back
            progressDialog.dismiss();
            userCallBack.complete(null);
            super.onPostExecute(aVoid);
        }
    }
}

I have the correct INTERNET persmission in my android manifest file as the permission are all coming up in the application settings in android. I did some research and found that it could be down to an underscore in my URL? Can anybody offer some help?

Thanks

Upvotes: 0

Views: 596

Answers (1)

Gabe Sechan
Gabe Sechan

Reputation: 93708

https://code.google.com/p/android/issues/detail?id=37577

Basically, an _ in a URL is an invalid character in a hostname (although not in a filename). Some browsers support it, but it causes problems. Android's default http implementation does not. You either need to change the url (preferred), or you need to use an HTTP library that supports it.

Upvotes: 1

Related Questions