0

I have tried many different ways to attempt to upload data from my Android app to a PHP script on my server using HttpURLConnection, but nothing shows up in the file that is created by PHP on the server. I had success using HTTPClient, but I had to make the switch to using HttpURLConnection. The app does NOT crash when it is run. I am sure that there is something simple that I am overlooking. My PHP script works fine, and even returns the expected response, but there is something I don't yet see that is wrong with my Android Code. Any help is apprecieated.

Here is the beginning of the PHP script:

  $data = $_POST["deviceSIG"];

Here is the code I am using to upload my data to the PHP script:

// the string deviceSIG is defined elsewhere and has been defined in the class.

private class MyAsyncTask extends AsyncTask<String, Integer, String>{
            @Override
            protected String doInBackground(String... params)           
     try{
                URL url = new URL("http://192.168.10.199/user_script.php");

                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.connect();             

                OutputStream outputStream = conn.getOutputStream();
                OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
                writer.write(deviceSIG);
                writer.close();
                outputStream.close();

                // read response
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(conn.getInputStream()));

                String inputLine;
                StringBuffer response = new StringBuffer();
                while ((inputLine = in.readLine()) != null) { response.append(inputLine); }
                in.close();

                result = response.toString();   


                // disconnect
                conn.disconnect();              

} catch (UnsupportedEncodingException e) {
    e.printStackTrace();                
} catch (ClientProtocolException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

return result;  

    }               
//-------------------------------------------------------------------------------

            protected void onProgressUpdate(Integer... progress){
                progBar.setProgress(progress[0]);
            }

//-------------------------------------------------------------------------------
            protected void onPostExecute(String result){
                progBar.setVisibility(View.GONE);

    String rawEcho = result;
    String[] Parts = rawEcho.split("~");
    String echo = Parts[1]; 
    String UIID = "User ID: " + echo;

    try {

    FileOutputStream fOS = openFileOutput("Info.txt", Context.MODE_APPEND);
    fOS.write(newLine.getBytes());
    fOS.write(UIID.getBytes());
    fOS.close();

    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
        }   

            }
Krang
  • 53
  • 2
  • 10
  • why are you not using the volley library? – Manny265 Jan 21 '16 at 21:44
  • Thank you very much for taking a look and replying. The reasons why I don't rely on libraries are: it makes me a better programmer if I learn why my code does what it does, and why it may crash; I don't know how to tweak/massage libraries to work with the many different types of Android devices, e.g. the project I am working on now works fine on my smartphone but needed tweaking to work on my tablet. – Krang Jan 22 '16 at 17:26

2 Answers2

5

After about 20 days of searching and testing, I have a working solution. Both Android and Oracle should have posted a simple commented example like this, it would have saved me and others a lot of time.

Credit goes to Xin Meng on this post for pointing me in the right direction about "the header, the content, the format of the request" to use.

Credit also goes to jmort253 on Can you explain the HttpURLConnection connection process? for his code and the explanation he posted (I modified his code to fit my project, of course).

I am a better programmer now, because I took the time to try to understand why my original code failed.

Below is my commented code that works to post a text string to my PHP script, and I hope it helps others who are having trouble. If anyone sees room for emprovement, please post a comment.:

On the PHP side:

$data = $_POST["values"];  // this gets the encoded and formatted string from the Android app.

On the Android side:

import java.net.HttpURLConnection;


// from another place in my code, I used:
// This calls the AsyncTask class below.
new POSTAsyncTask().execute(); 

//--------------------------------------------------

private class POSTAsyncTask extends AsyncTask<String, Integer, String>{
        //    AsyncTask<Params, Progress, Result>.
        //    Params – the type (Object/primitive) you pass to the AsyncTask from .execute() 
        //    Progress – the type that gets passed to onProgressUpdate()
        //    Result – the type returns from doInBackground()

@Override
protected String doInBackground(String... params) {

String phpPOST = null; // make sure this variable is empty
try {
// deviceSIG is defined in another part of the code, and is a text string of values.
// below, the contents of deviceSIG are encoded and populated into the phpPOST variable for POSTing.
// the LACK of encoding was one reason my previous POST attempts failed.
phpPOST = URLEncoder.encode(deviceSIG, "UTF-8");

} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

try {

// Populate the URL object with the location of the PHP script or web page.
URL url = new URL("http://192.168.10.199/user_script.php");

// This is the point where the connection is opened.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

// "(true)" here allows the POST action to happen.
connection.setDoOutput(true);

// I will use this to get a string response from the PHP script, using InputStream below.
connection.setDoInput(true); 

// set the request method.
connection.setRequestMethod("POST");

// This is the point where you'll know if the connection was
// successfully established. If an I/O error occurs while creating
// the output stream, you'll see an IOException.
OutputStreamWriter writer = new OutputStreamWriter(
        connection.getOutputStream());

// write the formatted string to the connection.
// "values=" is a variable name that is passed to the PHP script.
// The "=" MUST remain on the Android side, and MUST be removed on the PHP side.
// the LACK of formatting was another reason my previous POST attempts failed.
writer.write("values=" + phpPOST);

// Close the output stream and release any system resources associated with this stream. 
// Only the outputStream is closed at this point, not the actual connection.
writer.close();

//if there is a response code AND that response code is 200 OK, do stuff in the first if block
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
    // OK

    // otherwise, if any other status code is returned, or no status
    // code is returned, do stuff in the else block
} else {
    // Server returned HTTP error code.
}

//                  Get the string response from my PHP script:
    InputStream responseStream = new 
        BufferedInputStream(connection.getInputStream());

    BufferedReader responseStreamReader = 
        new BufferedReader(new InputStreamReader(responseStream));

    String line = "";
    StringBuilder stringBuilder = new StringBuilder();

    while ((line = responseStreamReader.readLine()) != null) {
        stringBuilder.append(line).append("\n");
    }
    responseStreamReader.close();

    String response = stringBuilder.toString();

//  Close response stream:

    responseStream.close();


result = response.toString();   


// Disconnect the connection:
    connection.disconnect();                    
//--------------------------------

} catch (MalformedURLException e) {
// ...
} catch (IOException e) {
// ...
}               
return result; // when I had this as 'return null;', I would get a NullPointerException in String that equaled the result variable.          
}
Community
  • 1
  • 1
Krang
  • 53
  • 2
  • 10
0

Android 6.0 suggest to use the HttpURLConnection to send HTTP request, I make a example project base on the Book of Recipe of Android on GitHub:

https://github.com/xinmeng1/HttpUrlConnectionREST

which include send GET/POST(form data or multi part) HTTP request. If you need the book, I can send the relative Chapters for the usage of HttpURLConnection.

Xin Meng
  • 1,982
  • 3
  • 20
  • 32
  • Thank you very much for taking a look and replying. I'll took a look at your github post, but I didn't know how to integrate it into my project, because my understanding of the correct way to use HttpURLConnection is limited. – Krang Jan 22 '16 at 17:28
  • After you review the example, you will find it is very simple. The sample has encapsulated it to a util class (.util.RestUtil). You can copy all the files in the package named `util`, then imitate the usage in the activity. Such as if you want to use the POST, you just imitate the usage in [this file](https://github.com/xinmeng1/HttpUrlConnectionREST/blob/master/app/src/main/java/tk/mengxin/httpurlconnectionrest/PostActivity.java) – Xin Meng Jan 22 '16 at 23:33
  • There are 4 step to use this util: 1. prepare the parameters of POST. 2. construct the `RestTask postTask` with the parameters. 3. Add the callback function. 4. Execute the AsyncTask. – Xin Meng Jan 22 '16 at 23:37
  • If you want to understand the theory of using HttpURLConnection to send HTTP request, you need to understand the basic knowledge of HTTP request.(the header, the content, the format of the request...) firstly. Then you could use one of the package capture tool (Fiddler2 is best for Android I think) to try to capture some package to debug your project. By the way, java callback theory is also important to understand the AsyncTask. – Xin Meng Jan 22 '16 at 23:42