使用模拟器和HttpURLConnection的未知主机异常

时间:2016-03-18 02:12:59

标签: java android emulation

我目前正处于在Android工作室开发Android应用程序的最后阶段。构建APK文件以在设备上运行它们分离到Android工作室模拟器之一。我和安迪安卓模拟器一起去了。我安装了APK,但是当我尝试登录时,即连接到服务器,我得到了一个未知的主机异常,如下所示:

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

我的android清单文件中有正确的INTERNET持久性,因为权限都在android的应用程序设置中出现。我做了一些研究,发现它可能是我网址中的下划线?有人可以提供一些帮助吗?

由于

1 个答案:

答案 0 :(得分:1)

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

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