Reputation: 650
Android use CookieManager to manage cookies. But there only have one method 'removeAllCookies()' to remove cookie and this removed all cookies. Now I want to remove a cookie associated with a specified url only, and other cookies don't be removed. In this situation, how can I do?
Upvotes: 5
Views: 3658
Reputation: 9990
Two other answers work for the version before Lollipop. In newer versions you should replace:
sCookieSyncManager.sync();
with:
sCookieManager.flush();
Upvotes: 0
Reputation: 34006
I made some minor changes in @summerxiaqing's answer and I checked it works. (Added https, changed empty check to TextUtils.isEmpty, passed CookieManager by argument)
public static void clearCookieByUrl(String url, CookieManager pCookieManager, CookieSyncManager pCookieSyncManager) {
Uri uri = Uri.parse(url);
String host = uri.getHost();
clearCookieByUrlInternal(url,pCookieManager,pCookieSyncManager);
clearCookieByUrlInternal("http://." + host,pCookieManager,pCookieSyncManager);
clearCookieByUrlInternal("https://." + host,pCookieManager,pCookieSyncManager);
}
private static void clearCookieByUrlInternal(String url, CookieManager pCookieManager, CookieSyncManager pCookieSyncManager) {
if (TextUtils.isEmpty(url)) {
return;
}
String cookieString = pCookieManager.getCookie(url);
Vector<String> cookie = getCookieNamesByUrl(cookieString);
if (cookie == null || cookie.isEmpty()) {
return;
}
int len = cookie.size();
for (int i = 0; i < len; i++) {
pCookieManager.setCookie(url, cookie.get(i) + "=-1");
}
pCookieSyncManager.sync();
}
private static Vector<String> getCookieNamesByUrl(String cookie) {
if (TextUtils.isEmpty(cookie)) {
return null;
}
String[] cookieField = cookie.split(";");
int len = cookieField.length;
for (int i = 0; i < len; i++) {
cookieField[i] = cookieField[i].trim();
}
Vector<String> allCookieField = new Vector<String>();
for (int i = 0; i < len; i++) {
if (TextUtils.isEmpty(cookieField[i])) {
continue;
}
if (!cookieField[i].contains("=")) {
continue;
}
String[] singleCookieField = cookieField[i].split("=");
allCookieField.add(singleCookieField[0]);
}
if (allCookieField.isEmpty()) {
return null;
}
return allCookieField;
}
Inside the Activity
mContext = getApplicationContext();
CookieManager mCookieManager = CookieManager.getInstance();
CookieSyncManager mCookieSyncManager = CookieSyncManager.createInstance(mContext);
clearCookieByUrl("http://example.com", mCookieManager, mCookieSyncManager);
Upvotes: 4
Reputation: 21
1, Android have not support this interface.
2, A work around in our project.
sCookieManager = CookieManager.getInstance();
public static void clearCookieByUrl(String url) {
Uri uri = Uri.parse(url);
String host = uri.getHost();
clearCookieByUrlInternal(url);
clearCookieByUrlInternal("http://." + host);
}
/**
* clear cookie by url
* @param url
*/
private static void clearCookieByUrlInternal(String url) {
if (Utils.isStringEmpty(url)) {
return;
}
String cookieString = sCookieManager.getCookie(url);
Vector<String> cookie = getCookieNamesByUrl(cookieString);
if (cookie == null || cookie.isEmpty()) {
return;
}
int len = cookie.size();
for (int i = 0; i < len; i++) {
sCookieManager.setCookie(url, cookie.get(i) + "=-1");
}
sCookieSyncManager.sync();
}
private static Vector<String> getCookieNamesByUrl(String cookie) {
if (Utils.isStringEmpty(cookie)) {
return null;
}
String[] cookieField = cookie.split(";");
int len = cookieField.length;
for (int i = 0; i < len; i++) {
cookieField[i] = cookieField[i].trim();
}
Vector<String> allCookieField = new Vector<String>();
for (int i = 0; i < len; i++) {
if (Utils.isStringEmpty(cookieField[i])) {
continue;
}
if (!cookieField[i].contains("=")) {
continue;
}
String[] singleCookieField = cookieField[i].split("=");
allCookieField.add(singleCookieField[0]);
}
if (allCookieField.isEmpty()) {
return null;
}
return allCookieField;
}
NOTE: In some android version(I do not have the exact version number, my experience is android 2.3), system will use host as the cookie domain, and on the other hand, system will use '.' + host as the cookie domain. So a better way is clear both of them.
Upvotes: 2