Question

In my application I send a POST request to a server, and receive a response from the server. And from the response I gather different cookies, user information specifically. So, I send a login request and receive the cookies after the server responds, to persist the login. In Android 4.3 and below, I receive the cookies just fine and user logs in successfully. But in Android 4.4, the user logs successfully, but no cookies are being received.

Has Android changed something significant for this to occur? Here is my code below if anyone has any suggestions.

private URL urlObj;
private HttpURLConnection connection;
private DataOutputStream dataOs;


private ArrayList<String> schools;
private ArrayList<Post> schoolPosts;
private String schoolID;
private String name;

private String userLoginCookie, sessionSeedCookie, sessionUidCookie, sPrefCookie;

private Context context;
private CookieStore store;

public DataParser(Context _context) {
    context = _context;
}

//First call whenever connecting across the user's network
private void establishConnection() throws IOException {
    urlObj = new URL(url);
    connection = (HttpURLConnection) urlObj.openConnection();
    CookieManager cookieManager = new CookieManager();

    cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
    CookieHandler.setDefault(cookieManager);
    store = cookieManager.getCookieStore();

    getCookies();
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
    connection.setRequestProperty("Cookie", sessionSeedCookie+";"+sessionUidCookie+";"+userLoginCookie+";"+sPrefCookie);
    connection.setDoOutput(true);
    connection.setUseCaches(false);

    dataOs = new DataOutputStream(connection.getOutputStream());
}

//Called after communication is complete
private void disconnectAll() throws IOException {
    connection.disconnect();
    dataOs.close();
}

private void getCookies() {
    SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
    userLoginCookie = settings.getString(USER_LOGIN, BLANK);
    Log.d(LOG, "Cookie: "+userLoginCookie);
    sessionSeedCookie = settings.getString(SESS_SEED, BLANK);
    Log.d(LOG, "Cookie: "+sessionSeedCookie);
    sessionUidCookie = settings.getString(SESS_UID, BLANK);
    Log.d(LOG, "Cookie: "+sessionUidCookie);
    sPrefCookie = settings.getString(S_PREF, "sPref="+BLANK);
    Log.d(LOG, "Cookie: "+sPrefCookie);
}

private void updateCookies() {
    SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
    SharedPreferences.Editor editor = settings.edit();

    List<HttpCookie> cookieList = store.getCookies();
    for(int i=0; i<cookieList.size(); i++) {
        if(cookieList.get(i).getName().equals(USER_LOGIN)) 
            editor.putString(USER_LOGIN, cookieList.get(i).toString());
        else if(cookieList.get(i).getName().equals(SESS_SEED)) 
            editor.putString(SESS_SEED, cookieList.get(i).toString()); 
        else if(cookieList.get(i).getName().equals(SESS_UID)) 
            editor.putString(SESS_UID, cookieList.get(i).toString());
        else
            Log.d(LOG, "Found Extra Cookie: "+cookieList.get(i).getName());
    }
    sPrefCookie = settings.getString(S_PREF, "sPref="+BLANK);

    editor.commit(); //Save changes to the SharedPreferences
}       

//Logins User into Walkntrade
public String login(String email, String password) throws IOException {
    establishConnection(); //Instantiate all streams and opens the connection

    String query= "intent=login&password="+password+"&email="+email+"&rememberMe=true";
    dataOs.writeBytes(query);
    Log.d(LOG, "" + connection.getResponseCode());
    updateCookies();

    String response = readInputAsString(connection.getInputStream());

    Log.d(LOG, "Connection Status: "+response);

    disconnectAll();
    return response;
}

//Logs user out of Walkntrade
public void logout() throws IOException { 
    establishConnection();

    String query = "intent=logout";
    dataOs.writeBytes(query);
    Log.d(LOG, "" + connection.getResponseCode());
    updateCookies();

    disconnectAll();
}

//Returns user login status
public static boolean isUserLoggedIn(Context _context) {
    SharedPreferences settings = _context.getSharedPreferences(PREFS_NAME, 0);
    boolean isUserLoggedIn = settings.getBoolean(DataParser.CURRENTLY_LOGGED_IN, false);

    return isUserLoggedIn;
}

public String getUserName() throws IOException{
    establishConnection();

    String query = "intent=getUserName";
    dataOs.writeBytes(query);
    Log.d(LOG, ""+connection.getResponseCode());
    updateCookies();

    String response = readInputAsString(connection.getInputStream());

    disconnectAll();
    return response;
}

public String getUserAvatar() throws IOException {
    establishConnection();

    String query = "intent=getAvatar";
    dataOs.writeBytes(query);
    Log.d(LOG, ""+connection.getResponseCode());
    updateCookies();

    String response = readInputAsString(connection.getInputStream());

    disconnectAll();
    return response;
}
Was it helpful?

Solution 2

I fixed the problem. I switched from HttpUrlConnection and other java.net stuff to AndroidHttpClient and other Apache Http classes. Cookies are now retrieved from Android API 19.

[EDIT] I used AndroidHttpClient (http://developer.android.com/reference/android/net/http/AndroidHttpClient.html) and I followed a couple Apache Http tutorials. So after I changed the code around a little bit, it looks like this:

private AndroidHttpClient httpClient; //Android Client, Uses User-Agent, and executes request
private HttpContext httpContext; //Contains CookieStore that is sent along with request
private CookieStore cookieStore; //Holds cookies from server
private HttpPost httpPost; //Contains message to be sent to client
private final String USER_AGENT = System.getProperty("http.agent"); //Unique User-Agent of current device

//First call whenever connecting across the user's network
private void establishConnection() {
    cookieStore = new BasicCookieStore();
    httpContext = new BasicHttpContext();
    httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); //Attach CookieStore to the HttpContext

    getCookies(); //Retrieve currently stored cookies

    httpClient = AndroidHttpClient.newInstance(USER_AGENT);
    httpPost = new HttpPost(url);
    httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
    httpPost.setHeader("Cookie", sessionSeedCookie + ";" + sessionUidCookie + ";" + userLoginCookie + ";" + sPrefCookie);
}

//Called after communication is complete
private void disconnectAll() {
    httpClient.close();
}

//Sends out POST request and returns an InputStream
private InputStream processRequest(String query) throws IOException{
    httpPost.setEntity(new StringEntity(query)); //wraps the query into a String entity
    HttpResponse response = httpClient.execute(httpPost, httpContext); //Executes the request along with the cookie store
    Log.i(TAG, "Server Response Code: " + response.getStatusLine().getStatusCode()); //Reads response code from server

    updateCookies();

    return response.getEntity().getContent();
}

//Logins User into Walkntrade
public String login(String email, String password) throws IOException {
    establishConnection(); //Instantiate all streams and opens the connection
    String query= "intent=login&password="+password+"&email="+email+"&rememberMe=true";

    InputStream inputStream = processRequest(query);
    String serverResponse = readInputAsString(inputStream); //Reads message response from server

    disconnectAll();
    return serverResponse;
}

OTHER TIPS

This code worked fine for me prior to KitKat 4.4 update -

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

//handle cookies
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

It broke after 4.4.2 (at least that's when I noticed it), and cookies were no longer received. Simply moving the CookieManager and CookieHandler before opening the urlConnection fixed it again .. bizarre that it worked before! eg.

//handle cookies
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top