title: Using Cookies across Activities when using HttpClient
body: <p>I'm trying a simple app to read in the HTML of a website, and tranform it to create an easily readable UI in Android (This is an exersize in learning android, not to make a useable app). The problem I'm having is persisting a users session across Activities and then using the session in a <code>HttpClient</code> once recalled. </p>
  
  <p>I would like to do this "Correctly", the recommended approach seem to be to use <code>CookieManager</code>. I've had problems with this however - I cannot seem to find the "Correct" way to take a <code>Cookie</code> from the <code>CookieManager</code> and use it in a later instantiation of <code>HttpClient</code> in a seperate Activities.</p>
  
  <p>When using a <code>CookieManager</code> I can save the <code>Cookie</code> and the <code>Cookie</code> is then in scope in other Activities (See code snippet 2). I haven't found how to use this later (See code snippet 3) when requesting a page.</p>
  
  <p>Enough talking, here is some code. First my login action and Cookie storage:  </p>
  
  <pre><code>private OnClickListener loginActionListener = new OnClickListener() 
  {
      public void onClick(View v) 
      {
          EditText usernameTextView = (EditText) findViewById(R.id.Username);
          EditText passwordTextView = (EditText) findViewById(R.id.Password);
          String username = usernameTextView.getText().toString();
          String password = passwordTextView.getText().toString();
  
          try {
              HttpPost postMethod = new HttpPost(URI);                
              HttpParams params   = new BasicHttpParams();
  
              params.setParameter("mode", "login");
              params.setParameter("autologin", true);
              params.setParameter("username", username);
              params.setParameter("password", password);
              postMethod.setParams(params);
  
              DefaultHttpClient httpClient = new DefaultHttpClient();
              HttpResponse response        = httpClient.execute(postMethod);
              List&lt;Cookie&gt; cookies = httpClient.getCookieStore().getCookies();
  
              if(cookies != null)
              {
                  for(Cookie cookie : cookies)
                  {
                      String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();                        
                      CookieManager.getInstance().setCookie(cookie.getDomain(), cookieString);  
                  }
              }
              CookieSyncManager.getInstance().sync();
  
              Intent intent = new Intent(v.getContext(), IndexAction.class);
              startActivity(intent);
      } catch (Exception e) {...}
  }
  </code></pre>
  
  <p>The startup Activity which decides wether to make the user login or go to the index is below. You can see from this code that the cookie is in scope and can be read:  </p>
  
  <pre><code>public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      CookieSyncManager.createInstance(this);
  
      if(CookieManager.getInstance().getCookie(URI) == null)
      {
          Intent intent = new Intent(this, LoginAction.class);
          startActivity(intent);
      }
      else
      {
          Intent intent = new Intent(this, IndexAction.class);
          startActivity(intent);
      }
  }
  </code></pre>
  
  <p>But from my code to read the Index page I'm hoping you can suggest what i'm missing:  </p>
  
  <pre><code>@Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      CookieSyncManager.createInstance(this);
  
      try
      {
              HttpGet getMethod = new HttpGet(URI_INDEX);  
  
              HttpParams params   = new BasicHttpParams();                        
              HttpConnectionParams.setConnectionTimeout(params, 30000);
              HttpConnectionParams.setSoTimeout(params, 30000);
  
              // This code results in a ClassCastException, I'm assuming i've found a red herring with this solution.
              // HttpContext localContext = new BasicHttpContext();    
              // localContext.setAttribute(ClientContext.COOKIE_STORE, CookieManager.getInstance().getCookie(URI));
  
              DefaultHttpClient httpClient = new DefaultHttpClient(params);
              HttpResponse response        = httpClient.execute(getMethod);
  
              if(response.getStatusLine().getStatusCode() &gt; 299 &amp;&amp; response.getStatusLine().getStatusCode() &lt; 400)
              {
                  // Not logged in doesn't give a redirect response. Very annoying.
              }
  
              final char[] buffer = new char[0x10000];
              StringBuilder out = new StringBuilder();
              Reader in = new InputStreamReader(response.getEntity().getContent(), "UTF-8");
              int read = 0;
              while (read&gt;=0)
              {
                read = in.read(buffer, 0, buffer.length);
                if (read&gt;0) {
                  out.append(buffer, 0, read);
                }
              }
  
              String returnString = out.toString();
      } catch (ClientProtocolException e) {...}
  }
  </code></pre>
  
  <p>The <code>HttpClient</code> on <code>execute(getMethod)</code> isn't using the Cookie (double checked this in debug) to pull back the page. It would be great if someone could fill this hole in my knowledge.</p>
  
  <p>Thanks in advance.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>When commented code is added back in (with the <code>httpClient.execute(getMethod)</code> method change to <code>httpClient.execute(getMethod, localContext)</code>) this strack trace is produced - Assumedly because i'm filling the attribute <code>ClientContext.COOKIE_STORE</code> with a <code>Cookie</code> <code>String</code> rather than a <code>CookieStore</code>:</p>
  
  <pre><code>*org.apache.http.client.protocol.RequestAddCookies.process(RequestAddCookies.java:88), org.apache.http.protocol.BasicHttpProcessor.process(BasicHttpProcessor.java:290), org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:160), org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401)
  org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487), 
  com.testapp.site.name.IndexAction.onCreate(IndexAction.java:47), 
  android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047), 
  android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611), 
  android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663), 
  android.app.ActivityThread.access$1500(ActivityThread.java:117), 
  android.app.ActivityThread$H.handleMessage(ActivityThread.java:931), 
  android.os.Handler.dispatchMessage(Handler.java:99), 
  android.os.Looper.loop(Looper.java:123), 
  android.app.ActivityThread.main(ActivityThread.java:3683), 
  java.lang.reflect.Method.invokeNative(Native Method), 
  java.lang.reflect.Method.invoke(Method.java:507), 
  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839), 
  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597), 
  dalvik.system.NativeStart.main(Native Method)*
  </code></pre>