使用模拟器和HttpURLConnection的未知主机异常 [英] Unknown Host Exception using emulator and HttpURLConnection

查看:140
本文介绍了使用模拟器和HttpURLConnection的未知主机异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前处于在Android Studio上开发Android应用程序的最后阶段。构建了APK文件,以便在与Android Studio模拟器之一不同的设备上运行它们。我选择了Andy android模拟器。我安装了APK,但是当我尝试登录即连接服务器时,出现未知主机异常,如下所示:

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)

服务器请求代码如下:

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);
        }
    }
}

我有正确的Internet权限在我的android清单文件中,因为权限全部出现在android的应用程序设置中。我进行了一些研究,发现URL可能下划线了吗?有人可以提供帮助吗?

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?

谢谢

推荐答案

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

基本上,URL中的_是主机名中的无效字符(尽管不是文件名)。某些浏览器支持它,但是会引起问题。 Android的默认http实现没有。您要么需要更改url(首选),要么需要使用支持它的HTTP库。

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.

这篇关于使用模拟器和HttpURLConnection的未知主机异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆