安卓上的WebView和Cookies

60

我在appspot上有一个应用程序,在常规浏览器中可以正常使用,但是在Android WebView中使用时,无法设置和读取Cookie。顺便说一下,我不是要在这个Web应用程序之外获取Cookie,一旦WebView访问了URL,所有处理、ids等都可以留在那里,我只需要在该应用程序内部进行会话管理。第一个屏幕也可以正常加载,因此我知道WebView + 服务器交互没有问题。

我查看了WebSettings类,没有像setEnableCookies这样的调用。

我像这样加载URL:

public class MyActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);       
    WebView webview = new WebView(this);
    setContentView(webview);      
    webview.loadUrl([MY URL]);
  }
  .. 
}
任何想法?

2
你百分之百确定这与JavaScript默认关闭无关吗? - Jim Blackler
2
我刚刚检查过了,不是那样。感谢您的输入。 - burak bayramli
@burakbayramli,你找到这个问题的答案了吗? - dark_illusion_909099
5个回答

100

如果您使用的是Android Lollipop即SDK 21,则:

CookieManager.getInstance().setAcceptCookie(true);

不会生效。你需要使用:

CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);

我遇到了同样的问题,上面的代码行解决了我的问题。


1
我正在使用minSdk 16,targetsdk 23,但即使我使用setAcceptCookie(true),它也无法正常工作。 - kommradHomer
你正在测试的设备的操作系统版本是什么? - Huzefa Gadi
19
CookieManager cookieManager = CookieManager.getInstance(); 如果(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // 在Lollipop及以上版本中,设置WebView接受第三方Cookie cookieManager.setAcceptThirdPartyCookies(webView,true); } else { // 在Lollipop以下的版本中,设置WebView接受Cookie cookieManager.setAcceptCookie(true); } - Clive Jefferies
7
setAcceptThirdPartyCookies有两个参数。用法:CookieManager.getInstance().setAcceptThirdPartyCookies(myWebview, true); - Federico Picci
2
这对任何人有用吗?我仍然遇到问题,如果有人能帮忙,我会非常感激。 - dark_illusion_909099
显示剩余3条评论

48

以下内容来自Android文档:

CookieSyncManager 用于在RAM和永久存储之间同步浏览器cookie。为了获得最佳性能,浏览器cookie保存在RAM中。通过一个定时器驱动的单独线程保存cookie。

要使用 CookieSyncManager,主机应用程序在应用程序启动时必须调用以下内容:

CookieSyncManager.createInstance(context)

为了进行同步设置,主机应用程序必须调用

CookieSyncManager.getInstance().startSync()

在Activity.onResume()中调用

 CookieSyncManager.getInstance().stopSync()

在Activity.onPause()中。

为了实现即时同步,而非等待计时器触发,主机可以调用

CookieSyncManager.getInstance().sync()

同步间隔为5分钟,因此您仍需要手动强制同步,例如在onPageFinished(WebView, String)中。请注意,即使sync()是异步进行的,因此不要在活动关闭时刚好进行同步。

最后,像这样的代码应该可以正常工作:

// use cookies to remember a logged in status   
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().startSync();
WebView webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
setContentView(webview);      
webview.loadUrl([MY URL]);

尝试过这个方法,但我并不是想从Webview中取出cookies。两个不同的Webview loadUrl调用之间,cookies可能会消失,这没关系。我的问题是在“同一会话”中cookies无法正常工作。 - burak bayramli
还可以查看这个链接:https://dev59.com/anI-5IYBdhLWcg3w0cOG - Pentium10
5
此外,如果您使用WebView引用存储在本地文件系统上的资源,则需要在Build.VERSION.SDK_INT >= 12时调用CookieManager.setAcceptFileSchemeCookies(true)。这个调用必须在CookieSyncManager或CookieManager的第一次实例化之前。 - Robin Davies
@RobinDavies 你救了我的一天! - Mandrake
1
从文档中得知:"此类已在API级别21中弃用。WebView现在会根据需要自动同步cookie。您不再需要创建或使用CookieSyncManager。要手动强制同步,可以使用CookieManager方法CookieManager#flush,它是同步替代sync()的方法。" - Daniel Alder
CookieSyncManager现已被弃用。 - Rohit Singh

39

我明白了发生了什么。

当我通过服务端操作(访问URL)加载页面,并在Webview中查看从该操作返回的HTML时,第一个操作/页面将在该Webview中运行。但是,当您单击Web应用程序中的任何作用命令链接时,这些操作会启动新的浏览器。这就是为什么Cookie信息会丢失,因为您为Webview设置的第一个Cookie信息已经不存在了,我们在这里有一个单独的程序。

您必须拦截Webview上的单击事件,以便浏览永远不会离开应用程序,一切都保留在同一个Webview中。

  WebView webview = new WebView(this);      
  webview.setWebViewClient(new WebViewClient() {  
      @Override  
      public boolean shouldOverrideUrlLoading(WebView view, String url)  
      {  
        view.loadUrl(url); //this is controversial - see comments and other answers
        return true;  
      }  
    });                 
  setContentView(webview);      
  webview.loadUrl([MY URL]);

这解决了问题。


41
实际上,当覆盖shouldOverrideUrlLoading以使您的WebView处理所有URL链接时,应该简单地返回false。不需要使用view.loadUrl(url);。返回true实际上意味着您希望系统覆盖处理(可能是启动浏览器)。因此,如果您想要链接在您的webview中打开,请返回false。来源:http://developer.android.com/guide/webapps/webview.html#HandlingNavigation - Tony Chan
3
错误。错误。错误。Turbo是正确的:在此回调中绝对不应该调用view.loadUrl()。 - Brian Melton-Grace - MSFT
5
无论对错,第三方都不应该对答案的代码进行基本更改。如果你同意某个评论,请发布自己的答案或点赞该评论。 - Chris Stratton
1
坏坏坏,返回假! - user25

9
我的问题是同一会话内的 cookies 不起作用。
Burak: 我曾经也有同样的问题,启用 cookies 可以解决这个问题。
CookieManager.getInstance().setAcceptCookie(true);

嗨,Lucifer,我尝试了这个,但是我无法将邮件ID和密码详细信息存储在cookie中。 WebView是否存储详细信息?请帮帮我。当我第一次输入ID和PWD时,这些详细信息应该被保存,当我使用相同的用户ID和PWD登录时,这些详细信息应该被存储在cookie中并显示出来,然后我必须选择该ID。 WebView是否可以在cookie中存储详细信息?提前致谢。 - user1407203
我也跟随这个链接 https://dev59.com/OG035IYBdhLWcg3weP3f - user1407203
1
这个建议解决了我的问题,即在Android 2.2.1上应用程序重新启动时丢失了cookies。 - zasadnyy
完整解决方案请查看答案 https://dev59.com/CGQm5IYBdhLWcg3w6SlR#47868677 - Misha Akopov

1

CookieManager.getInstance().setAcceptCookie(true);通常情况下,如果您的WebView已经初始化,它应该可以正常工作。

或者尝试这个:

CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeAllCookie();
cookieManager.setAcceptCookie(true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接