I can’t get this one. Had an app that was working great. Then I updated my Razr Droid to ICS and things have changed.
Running a Drupal Server with Drupal Services Module. When I connect over wifi, everything works great. When I connect over 3g/4g however, the httpclient.execute() method takes 3-4 minutes instead of seconds. I put together the following sample code which recreates the problem. I should add that browser connection to the server over 4g works fine.. So I don’t think this is a simple wireless connection issue.
public class DrupalTestActivity extends Activity {
private Context mCtx;
public static long mSESSION_LIFETIME = 200000; // seconds.
final static String URL = "www.myDrupalServer.com";
final static String ENDPOINT = "rest/";
String mResponse = null;
String cookie;
TextView textView;
public class DoLogin extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
cookie = getCookie(mCtx);
return cookie;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
textView.setText(mResponse);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mCtx = this;
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.textView);
DoLogin task = new DoLogin();
task.execute();
}
protected String getCookie(Context ctx) {
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(mCtx);
Long timestamp = settings.getLong("sessionid_timestamp", 0);
Long currenttime = new Date().getTime() / 100;
String cookie = settings.getString("cookie", null);
if (cookie == null || (currenttime - timestamp) >= mSESSION_LIFETIME) {
JSONObject mUserAccount = UserAccount.getJSONUserAccount(ctx);
userLogin(mUserAccount);
return getCookie(ctx);
} else {
Log.d("COOKIE", cookie);
return cookie;
}
}
public String userLogin(JSONObject mUserAccount) {
String uri = URL + ENDPOINT + "user/login";
HttpPost httppost = new HttpPost(uri);
httppost.setHeader("Content-type", "application/json");
StringEntity se;
try {
HttpClient mHttpClient = new DefaultHttpClient();
HttpParams mHttpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(mHttpParams, 10000);
HttpConnectionParams.setSoTimeout(mHttpParams, 10000);
se = new StringEntity(mUserAccount.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
httppost.setEntity(se);
Log.d("STATUS", "CALLING DRUPAL");
HttpResponse response = mHttpClient.execute(httppost);
Log.d("STATUS", "LOGIN COMPLETE");
mResponse = EntityUtils.toString(response.getEntity());
// save the sessid and session_name
JSONObject obj = new JSONObject(mResponse);
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(mCtx);
SharedPreferences.Editor editor = settings.edit();
editor.putString("cookie", obj.getString("session_name") + "="
+ obj.getString("sessid"));
editor.putLong("sessionid_timestamp",
new Date().getTime() / 100);
editor.commit();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mResponse;
}
}
Here is class UserAccount, but I don’t really think it’s relevant..
public class UserAccount {
private String USER = "tester";
private String PASSWORD = "passtest";
private static Context mCtx;
public UserAccount(Context Ctx, String Username, String Password) {
mCtx = Ctx;
}
public void save(Context mCtx) {
// TODO This would really work better if we just passed in the Account
// Object
Map<String, String> mMap = new HashMap<String, String>();
mMap.put("username", USER);
mMap.put("password", PASSWORD);
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(mCtx);
SharedPreferences.Editor editor = settings.edit();
Iterator<?> iter = mMap.entrySet().iterator();
while (iter.hasNext()) {
@SuppressWarnings("rawtypes")
Map.Entry mEntry = (Map.Entry) iter.next();
editor.putString(mEntry.getKey().toString(), mEntry.getValue()
.toString());
}
editor.commit();
}
public static JSONObject getJSONUserAccount(Context ctx) {
SharedPreferences accountSettings = PreferenceManager
.getDefaultSharedPreferences(ctx);
String nUsername = accountSettings.getString("username", "tester");
String nPassword = accountSettings.getString("password", "dweeber");
JSONObject JSONUser = new JSONObject();
try {
JSONUser.put("password", nPassword);
JSONUser.put("username", nUsername);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return JSONUser;
}
}
LogCat output for the wifi connection.
07-02 16:49:32.812: I/System.out(12001): debugger has settled (1401)
07-02 16:49:33.319: D/dalvikvm(12001): threadid=1: still suspended after undo (sc=1 dc=1)
07-02 16:49:36.921: D/STATUS(12001): CALLING DRUPAL
07-02 16:49:37.749: D/libc(12001): Forward DNS query to netd(h=www.seinetest.com.php5-22.dfw1-1.websitetestlink.com s=^)
07-02 16:49:43.046: D/STATUS(12001): LOGIN COMPLETE
Time is a dozen seconds or so..
LogCat output on 3g/4g
07-02 16:52:36.171: I/System.out(12759): debugger has settled (1362)
07-02 16:52:36.687: D/dalvikvm(12759): threadid=1: still suspended after undo (sc=1 dc=1)
07-02 16:52:46.171: D/STATUS(12759): CALLING DRUPAL
07-02 16:52:47.265: D/libc(12759): Forward DNS query to netd(h=www.seinetest.com.php5-22.dfw1-1.websitetestlink.com s=^)
07-02 16:53:17.569: W/IInputConnectionWrapper(12759): getExtractedText on inactive InputConnection
07-02 16:53:17.593: W/IInputConnectionWrapper(12759): getExtractedText on inactive InputConnection
07-02 16:54:38.593: W/IInputConnectionWrapper(12759): getExtractedText on inactive InputConnection
07-02 16:54:38.616: W/IInputConnectionWrapper(12759): getExtractedText on inactive InputConnection
07-02 16:56:08.921: D/STATUS(12759): LOGIN COMPLETE
MUCH longer login time!!
Clearly, the getExtractedText is something new,but is it a cause or a result? I did a search on here for IInputConnectionWrapper getExtractedText and there is one question where someone asks what it’s significance is.. It was closed and marked as a bad question. 🙁
Additional details are Verizon carrier
Server is hosted on Rackspace Cloud Servers
Phone Verizon Droid Razr, Android 4.0.4
I’m really hopeful I can get some guidance here or my months of work are bust. Thanks a ton for any help at all.
I THINK I finally figured this out. I did some research and some tests.
Phone Droid Razr, ICS 4.0.4 Verizone wireless.
I polled three of my servers and google. All of my test servers are located on same cloud (RackSpace)
Response times were as follows.
Google: 42ms
My Server #1 100ms
My Server #2 96
My Server #3 – A test server with no Domain name registered running as http://www.seinetest.blah.blah.websitetestlink.com. Rackspace automatically does this until a domain name is registered with the server.. Response time 14445 ms.
Desktop Browser times to all four sites were unremarkable. So the problem HAD to be in the phone.. or did it?
After upgrade to ICS, this huge discrepancy in response times cropped up. I did find some data in the above links that other phones were having problems with ICS getting through proxies. I called Rackspace and the assured me the only difference between my registered domain name servers and server #3, was where the DNS pointers were pointing.. no proxies!
Leaving very little else to try, I registered server #3 with a domain name and WALLAH!
Response times from the ICS phone are equal to the other servers with registered domain names.. given that this all happened with the ICS upgrade I am inclined to think this is an ICS bug which I’ll be reporting.