I've been reading answers, questions, forums and blogs for 2 days now but can't fix my issue.
I've an AngularJS webApp working in a Native (SDK) Android App with a WebView.
Everything seems to work but when my application calls services that responds with the "Set-Cookie" header those cookies are not setted in the webview and, of course are neither sent in the next calls, so my app explodes.
The app works flawlessly in browser and cordova and "document.cookie" returns an empty string, so i know this is where it fails.
My webview is initialized like this:
public class Main extends AppCompatActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webview = (WebView) findViewById(R.id.webview);
webview.setWebViewClient(new mWebViewClient());
webview.getSettings().setAppCacheEnabled(true);
webview.getSettings().setDomStorageEnabled(true);
webview.getSettings().setSavePassword(true);
webview.getSettings().setAllowFileAccessFromFileURLs(true);
webview.getSettings().setAllowContentAccess(true);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setUserAgentString(...);
webview.loadUrl("file:///android_asset/www/index.html");
javascriptAPI = new JavascriptAPI(this);
webview.addJavascriptInterface(javascriptAPI, "jsAPI");
...
}
...
}
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().run();
CookieManager.getInstance().setAcceptCookie(true);
...
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(this);
}
^^^^^^^
THIS
WebView webview = (WebView) findViewById(R.id.webview);
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().run();
CookieManager.getInstance().setAcceptCookie(true);
CookieManager.getInstance().setAcceptFileSchemeCookies(true); <- THIS
CookieManager.getInstance().setAcceptThirdPartyCookies(webview, true); <- THIS
webview.setWebViewClient(new mWebViewClient());
webview.getSettings().setAppCacheEnabled(true);
...
There are three acceptCookie methods you need to worry about, and different behavior across several versions of Android to take into consideration.
1) I noticed your initial url is a file://
url. You may need to call CookieManager.getInstance().setAcceptFileSchemeCookies(true);
.
2) In Android Lollipop and greater, you may need to call CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
3) For Android versions < Lollipop, if you want cookies to be persisted (e.g., survive rotation), you have to take some steps to manually manage syncing.
First, to ensure that CookieSyncManager is initialized during application startup by adding it your appplication class' onCreate(), or extend this one.
public class CookieApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(this);
}
}
}
Second, you need to setup syncing for pre-lollipop devices, and finally to enable cookies. Here's an example activity that you could extend that sets up all the syncing for pre-Lollipop devices, and provides an enablesCookies(webView)
that should turn on all cookie types regardless of Android version (be advised there are security considerations to be made when calling these methods!). Note that all of the CookieManager.getInstance().set*Cookie*() methods must be called after the webView is initialized.
public class AppCompatCookieActivity extends AppCompatActivity {
@Override
public void onResume() {
super.onResume();
// start cookie syncing for pre-lollipop devices
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.getInstance().startSync();
}
}
@Override
public void onPause() {
// stop cookie syncing for pre-lollipop devices
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.getInstance().sync();
}
super.onPause();
}
public final void enableCookies(WebView webView) {
// enable javascript (has security implications!)
webView.getSettings().setJavaScriptEnabled(true);
// enable cookies.
CookieManager.getInstance().setAcceptCookie(true);
// enable fileScheme cookies (has security implications!)
// it is recommended to comment this out should you find it not necessary
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
CookieManager.getInstance().setAcceptFileSchemeCookies(true);
}
// enable third party cookies
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
}
}
}