26

In my Android app, each activity is filled with data from an xml file which is somewhere on the web. The website providing these files has a login mechanism, that works with cookies.

I know how to make a HTTP Request to the login page and receive a cookie. What I don't know is, how I can store it to re-use it in both other activities AND when the app is started the next time. The cookie is valid for a year, so the user of my app should log in once and then never again for a whole year.

How do I do that? I googled a lot, but either I used the wrong keywords or there are no simple solutions on the internet. I hope somebody here can help me.

Best regards and thanks in advance, Jan Oliver

janoliver
  • 7,744
  • 14
  • 60
  • 103
  • Are you using AndroidHttpClient? Have you confirmed that the are not being stored? I believe that the implementation of AndroidHttpClient deals with the cookie store for you in a persistent manner. – cistearns Nov 03 '10 at 00:23
  • 2
    They are stored in the way that following requests using the same httpclient recognize it. But they are not preserved after closing the app or switching the activity and creating new instances of httpclient. – janoliver Nov 03 '10 at 13:40

5 Answers5

19

Use a CookieSyncManager to store your cookie value. It can persist across application starts.

Beware of using CookieSyncManager inside of WebViewClient#shouldInterceptRequest on KitKat. It will deadlock.

EDIT

CookieSyncManager was deprecated in API 21:

This class was deprecated in API level 21. The WebView now automatically syncs cookies as necessary. You no longer need to create or use the CookieSyncManager. To manually force a sync you can use the CookieManager method flush() which is a synchronous replacement for sync().

Heath Borders
  • 30,998
  • 16
  • 147
  • 256
10

It looks like Android is using the default in memory implementation so you will need to create your own persistent cookie store.

This Java Tutorial outlines creating your own persistent store taking advantage of the default implementation. http://download.oracle.com/javase/tutorial/networking/cookies/custom.html

The sample has two todo's for storage (read/write) For storage I would just use SharedPreferences to store just the session cookie that you need and not persist any others.

The sample uses a shutdown hook which is not what you want in Android. In place of run() and the hook I would just have a new public method persist() that saves what you want, though that requires that you persist() the store by hand.

Given that you only have one or two cookies that matter you could save them in the add(...)

cistearns
  • 2,488
  • 21
  • 24
  • Thanks for the answer I was looking for. Unfortunately I solved it storing the login credentials now and logging in whenever I start the app. The HttpClient is then shared between Activites via a static Class. But thanks anyway! – janoliver Nov 05 '10 at 07:53
  • Using the Runtime addShutdownHook should be avoided on Android: from the Android documentation on that function "Note that on Android, the application lifecycle does not include VM termination, so calling this method will not ensure that your code is run. Instead, you should use the most appropriate lifecycle notification (Activity.onPause, say). " – cistearns Aug 28 '12 at 18:17
  • 3
    @janoliver you should not store the login credentials !? – seb Sep 17 '12 at 18:33
  • Saving Cookies in add() will not account for calls to remove() - you don't want to do that (at least, not without similar invocations for removal actions). – Brian Melton-Grace - MSFT Jul 02 '14 at 05:36
  • Well the original question was about how to persist cookies. The implication is that if you wanted full management you would need to fill out all the functions with your choice of management solution, and that the sample code use of shutdown hook was not good for Android. – cistearns Jul 03 '14 at 06:51
4

After you make your http call, you can grab the cookies like this

List<Cookie> cookies = httpclient.getCookieStore().getCookies();
if (cookies.isEmpty()) {
   Log.d(TAG,"no cookies received");
} else {
   for (int i = 0; i < cookies.size(); i++) {
      if(cookies.get(i).getName().contentEquals("PHPSESSID")) {
         PHPSESSID = cookies.get(i).getValue();
      }
   }
}

To send them back:

nameValuePairs.add(new BasicNameValuePair("PHPSESSID",phpsessid));
httppost.setEntity(new UrlEncodedFormEntity(aList));

aList is all your nameValuePairs

Janusz
  • 187,060
  • 113
  • 301
  • 369
Jim
  • 1,966
  • 3
  • 24
  • 33
  • Did you read my question? I was asking how to store the cookies in my app for future use in other activites and even other runs of my app. – janoliver Nov 03 '10 at 00:01
  • That is what the first part does, it extracts cookies that you have received from a site. In the example it is grabbing the cookie named "PHPSESSID". You can then store it in a String. The second part shows how to return the cookie to the server in pages at a later date. – Jim Nov 04 '10 at 10:28
  • what if I want to save all Cookies the server sends? not only those that I catch ? – Francisco Corrales Morales May 22 '14 at 16:03
4

LoopJ has a built in persistent cookie store that can be used with or without the loopj framework

https://github.com/loopj/android-async-http/blob/master/library/src/main/java/com/loopj/android/http/PersistentCookieStore.java

jptsetung
  • 9,064
  • 3
  • 43
  • 55
0

I wrote a simple class named CookieHelper and I've provided an example of how to use this class to help all users that facing the same problem : https://github.com/augustopicciani/HttpClient-save-cookies-to-file

Augusto Picciani
  • 788
  • 2
  • 11
  • 31