• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps HttpPost not working in Ice Cream Sandwich?

icydash

Newbie
Hey guys, I'm having trouble getting my code working on ICS. It worked perfectly on my old DroidX, but I just got the new Galaxy Nexus and my code just returns null every time, as if the app isn't connecting to my servers or it's using a GET request when it should be using POST. Below is my code, any help is appreciated:

Code:
   //---------------- AUTHENTICATE LOGIN ---------------------------
    public static String authenticateLogin (String usr, String password, String updateDataNames, String updateDataUsernames, String updateDataPhone, String updateDataRadius, String updateDataChecked, String updateGPS)
    {   	
	    String result = "";
    	ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>();
		pairs.add(new BasicNameValuePair("LoginUSR", usr));
		pairs.add(new BasicNameValuePair("LoginPASS", password));
		pairs.add(new BasicNameValuePair("Names", updateDataNames));
		pairs.add(new BasicNameValuePair("Usernames", updateDataUsernames));
		pairs.add(new BasicNameValuePair("Phone", updateDataPhone));
		pairs.add(new BasicNameValuePair("Radius", updateDataRadius));
		pairs.add(new BasicNameValuePair("Checked", updateDataChecked));
		pairs.add(new BasicNameValuePair("GPS", updateGPS));
    
		try 
		{
			HttpClient client = new DefaultHttpClient();
			HttpPost post = new HttpPost("http://www.[URL REMOVED].com/file.php");
			post.setEntity(new UrlEncodedFormEntity(pairs));
			HttpResponse response = client.execute(post);
			HttpEntity entity = response.getEntity();
			
			final InputStream is = entity.getContent();
			
			BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
			StringBuilder sb = new StringBuilder();
	        String line = null;
	        while ((line = reader.readLine()) != null) {
	                sb.append(line);
	        }
	        is.close();
 
	        result=sb.toString();
	        
		}
		catch(Exception e)
		{
			
			Log.e("log_tag", "Error in http connection "+e.toString());
		}
		//-------------------------------------
		
    	return result;
    }
}

EDIT: This thread better describes the problem I'm having and the reason why: http://stackoverflow.com/questions/10372940/android-httprequest-on-ics-fails

Apparently I can not do networking on main thread, I have to move it to a background thread, or use AsyncTask. I'm really not sure what either of those things mean / how to do them (newbie programmer here). Any help is appreciated.
 
when you call the above method, do something like so:

Code:
//...More code here

new AsyncTask<String, Void, String>() {
 
         String usr;
         String pass;
         String updateDataNames;
         String updateDataUsernames;
         String updateDataPhone;
         String updateDataRadius;
         String updateDataChecked;
         String updateGPS;
         String res;

         @Override
         protected String doInBackground(String... params) {
                 usr = params[0];
                 pass = params[1];
                 updateDataNames = params[2];
                 updateDataUsernames = params[3];
                 updateDataPhone = params[4];
                 updateDataRadius = params[5];
                 updateDataChecked = params[6];
                 updateGPS = params[7]; 
                 res = params[8]
                  
                 String res = null;

                 String result = YourStaticClass.authenticateLogIn(usr, pass, updateDataNames, updateDataUsernames, updateDataPhone, updateDataRadius, updateDataChecked, updateGPS);

                        if (result.equals("LoginOK")) {
                               SQLiteDatabase myDBlogin = null;
	                       myDBlogin = openOrCreateDatabase("uNearDatabase", MODE_PRIVATE, null);
	                       myDBlogin.execSQL("INSERT INTO uNearSettings (ID, Username, Password, Timeframe, Startup) VALUES ('1','"+user+"', '"+pass+"', 'true', 'true');");
	                       NEWdialog.dismiss();
	                       res = "Login credentials validated.";	
					        
	                       startService(new Intent(getApplicationContext(),uNearService.class));
                       } else if(result.equals("AuthError")) {
                              res = "Invalid Login Credentials.";
                       } else {
                              res = "Can not connect to uNear servers at this time. Try again later.";
                       }

                       return res;
            }

            @Override
            protected void onPostExecute(String res) {

                    //Do w/e you need to do with the res String here. (i.e. whatever comes after the code you provided. This method won't be called until the background thread has completely finished executed.
                      
            }
}.execute(usr, pass, updateDataNames, updateDataUsernames, updateDataPhone, updateDataRadius, updateDataChecked, updateGPS);

//...More code here
 
Thanks for your response! So, I call my authenticateLogin method within an "if statement," as shown below:

Code:
if (authenticateLogin(user, pass, "", "", "", "", "", "").equals("LoginOK"))
{
	SQLiteDatabase myDBlogin = null;
	myDBlogin = openOrCreateDatabase("uNearDatabase", MODE_PRIVATE, null);
	myDBlogin.execSQL("INSERT INTO uNearSettings (ID, Username, Password, Timeframe, Startup) VALUES ('1','"+user+"', '"+pass+"', 'true', 'true');");
	 NEWdialog.dismiss();
	result = "Login credentials validated.";	
					        
	startService(new Intent(getApplicationContext(),uNearService.class));
}
else if (authenticateLogin(user, pass, "", "", "", "", "", "").equals("AuthError"))
{
	result = "Invalid login credentials.";
}
else
{ 
	result = "Can not connect to uNear servers at this time. Try again later.";
}

I'm still not quite sure how I integrate your code with my code, but I really appreciate you're insight so far.





when you call the above method, do something like so:

Code:
new AsyncTask<String, Void, String>() {
 
         String usr;
         String pass;
         String updateDataNames;
         String updateDataUsernames;
         String updateDataPhone;
         String updateDataRadius;
         String updateDataChecked;
         String updateGPS;

         @Override
         protected String doInBackground(String... params) {
                 usr = params[0];
                 pass = params[1];
                 updateDataNames = params[2];
                 updateDataUsernames = params[3];
                 updateDataPhone = params[4];
                 updateDataRadius = params[5];
                 updateDataChecked = params[6];
                 updateGPS = params[7]; 

                 return YourStaticClass.authenticateLogIn(usr, pass, updateDataNames, updateDataUsernames, updateDataPhone, updateDataRadius, updateDataChecked, updateGPS);
            }

            @Override
            protected void onPostExecute(String result) {

                        //Do whatever you need to do with the String returned from the method here.
            }
}.execute(usr, pass, updateDataNames, updateDataUsernames, updateDataPhone, updateDataRadius, updateDataChecked, updateGPS);
 
I have modified the example to illustrate how you might implement it. After that, the res variable should hold the string result from your conditional.
 
After looking at the code again, I realized that my modifications won't necessarily work correctly. I have modified it again to ensure that the res String variable always has a value when it is used. Also, I moved the DB stuff into the background also, as DB access should also be placed in a seperate thread (though it is not as strictly enforced as network com).
 
Using http post and can't get it working for Android 3.0 or higher, just add this code underneath the onCreate function, and it should allow to be able to login!

// it allows for any http to connect, it makes the connection not strict
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
 
This was really helpful. I searched for a pretty long time for a solution like this (I used it for Android 4.0+).
 
Yes, on Android 4.0+, network calls cannot exist on the UI thread. It can be bypassed by the above example, but it really shouldn't be bypassed at all. That is one strict mode policy that I believe should be forced no matter what. Network call should NEVER exist on the UI thread, no matter what the circumstances.
 
Back
Top Bottom