With my code below, I have been able to save a cookie, but as soon as I close the application the cookie disappears.
How is this caused and how can I solve it?
package com.jkjljkj
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CookieSyncManager.createInstance(getBaseContext());
// Let's display the progress in the activity title bar, like the
// browser app does.
getWindow().requestFeature(Window.FEATURE_PROGRESS);
WebView webview = new WebView(this);
setContentView(webview);
webview.getSettings().setJavaScriptEnabled(true);
final Activity activity = this;
webview.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
// Activities and WebViews measure progress with different scales.
// The progress meter will automatically disappear when we reach 100%
activity.setProgress(progress * 1000);
}
});
webview.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//Users will be notified in case there's an error (i.e. no internet connection)
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
});
CookieSyncManager.getInstance().startSync();
CookieSyncManager.getInstance().sync();
//This will load the webpage that we want to see
webview.loadUrl("http://");
}
}
You have to tell the CookieSyncManager to sync after it has loaded the page in question. In your sample code, the onCreate method executes completely before the WebView tries to load the page, so the sync process (which happens asynchronously) will probably complete before the page is loaded.
Instead, tell the CookieSyncManager to sync onPageFinished in the WebViewClient. That should get you what you want.
The CookieSyncManager Documentation is a good read for how to do this properly.
Here is how you could set up your WebViewClient implementation to do this for you:
webview.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//Users will be notified in case there's an error (i.e. no internet connection)
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
public void onPageFinished(WebView view, String url) {
CookieSyncManager.getInstance().sync();
}
);
You would not need to tell the CookieSyncManager to sync elsewhere with this in place. I haven't tested this, so let me know if it works.
.sync() is to force a imediate sync ,and must be called after page load cause it sync RAM with cache , so cookie must be in ram before calling it .
System automatically sync it every 5 mintues if you use this scheme
onCreate:
CookieSyncManager.createInstance(context)
onResume:
CookieSyncManager.getInstance().startSync()
onPause:
CookieSyncManager.getInstance().stopSync()
I think you did not waited 5 mintues so system save cookie.
For those who are facing Problems with CookieManager class to make cookie persist even after closing the app, they should try the flush() function of CookieManager.
Please note that i haven't tried this, so if it works then please let me know too.
According to android documentation
void flush()
Ensures all cookies currently accessible through the getCookie API are written to persistent storage. This call will block the caller until it is done and may perform I/O.
Also in CookieSyncManager documnentation it is written that:
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(). CookieSyncManger link
Works perfectly for API 20+
myWebView.setWebViewClient(new WebViewClient(){
public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl){
Toast.makeText(MainActivity.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
public void onPageFinished(WebView webView, String url){
CookieManager.getInstance().flush();
}
}
);
Related
I have an App made using Android Webview, while using Wifi connection the initial page loaded displays ok, after switching to mobile data mode, the application shows the ERR_NAME_NOT_RESOLVED message at times.
Is there a workaround to hide this message until the page is correctly displayed? or to make it work when the connection is not good in the initial load?
Thanks for the insight.
You can ask the user to retry at that point of time either displaying there or by showing a popup with a message. If you get the network is strong enough load the same page again.
You can check the url that is getting loaded in your webview by doing this.
myWebView.setWebViewClient(new WebViewClient() {
#SuppressLint("NewApi")
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
});
I have a simple webview that loads a website. Once the website is loaded, I have the following to focus/scroll to the login box:
mWebview.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
mWebview.scrollTo(681, 100);
(I've heard that onPageFinished is deprecated, but it's working for me in 2.2>4.4, so I'm just leaving it for now.
Anyway, I would like some sort of way to monitor for when the user actually logs in, that way when the page is done loading for the second time, I can then call some js and forward them to another page, but I have no idea how to do that. :(
I can just do another onPageFinished after they log in, but I don't know how to start monitoring... In other words, I can't start another onPageFinished immediately after the current, because it just redirects automatically.
Does anyone have any suggestions? I would greatly appreciate it! :)
EDIT:
Here's the entirety (minus the import headers) of my MainActivity.java class.
public class MainActivity extends Activity {
private WebView mWebview ;
#Override
public void onBackPressed() {
if(mWebview.canGoBack() == true){
mWebview.goBack();
}else{
super.onBackPressed();
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mWebview = new WebView(this);
mWebview.getSettings().setJavaScriptEnabled(true); // enable javascript
mWebview.getSettings().setBuiltInZoomControls(true);
if(android.os.Build.VERSION.SDK_INT >= 11) {
mWebview.getSettings().setDisplayZoomControls(false);
}
final Activity activity = this;
mWebview.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(activity, description, Toast.LENGTH_SHORT).show();
}
});
mWebview .loadUrl("http://example.com");
setContentView(mWebview );
mWebview.setWebViewClient(new WebViewClient(){
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
mWebview.scrollTo(681, 100);
}
}
);
}
I think I might be missing a curly bracket, but ignore that for now, haha. So anyway, after mWebview.scrollTo (the last line), the webpage is done loading, and it just chills at the login page. After a user logs in, the page (obviously) starts to load and directs to another post-login URL. I'd like to check the URL with an if statement after the page is done loading for the second time.
Does that make more sense? Sorry, it's confusing me too, trying to explain it.
Usually there will be two separate URLs, one for the post log-in page and one for the pre log-in page. You can have an if statement that checks the URL to make sure you've logged in, and if you have, then it redirects/closes/whatever.
I had a similar issue here:
Closing a Webview in Android
So basically you just want to execute some JavaScript once you've logged in? I don't see why you can't have an if statement to check whether you're logged in or not, and if you're logged in, then execute the js.
Something like this maybe?
wv.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
if (url.contains(getString(R.string.loginURL))){
super.onPageFinished(view, url);
mWebview.scrollTo(681, 100);
}else if(url.contains(getString(R.string.loggedInURL))) {
wv.loadUrl(js goes here);
}
}
}
This will execute every time a page is finished loading in your WebView
I'm trying to call JS functions from Android native code, but they don't seem to be working. I've tried many solutions but to no solution. Here is my code:
public class MainActivity extends Activity {
private WebView webView;
#SuppressLint("SetJavaScriptEnabled")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView1);
webView.setWebViewClient(new MyCustomWebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.loadUrl("http://google.com");
}
private class MyCustomWebViewClient extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
webView.loadUrl("javascript:alert('shadow');");
Toast.makeText(getApplicationContext(), "DONE", Toast.LENGTH_LONG).show();
}
}
}
Please help.
Thanks
You can't do alert() with Android's WebView. If you want to show alert dialogs, you need to handle it in your Activity code or use a WebChromeClient. Per the docs:
Creating and setting a WebChromeClient subclass. This class is called
when something that might impact a browser UI happens, for instance,
progress updates and JavaScript alerts are sent here (see Debugging
Tasks).
See: https://developer.android.com/reference/android/webkit/WebView.html
With a WebView you can still write a JavaScript function that sets the value of a textbox to some string. If you need specific code to help you with this, let me know. If you've gotten this far though, you probably can handle it on your own is my guess.
Edit 1
First create a method in JavaScript called sendValueToAndroid()
myWebView.loadUrl("javascript:sendValueToAndroid()");
In the JavaScript method, call an exposed method in your Android code.
function sendValueToAndroid()
{
val divValue = ...
Android.sendValueToAndroid(divValue);
}
Expose a method in the Android app in any object of your choosing.
#JavascriptInterface
public String sendValueToAndroid(String val)
{
//do something in your app
}
Basically, what you're doing is telling the WebView to invoke a JavaScript method which invokes a callback method in your own app.
With my code below, I have been able to save a cookie, but as soon as I close the application the cookie disappears.
How is this caused and how can I solve it?
package com.jkjljkj
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.webkit.CookieSyncManager;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CookieSyncManager.createInstance(getBaseContext());
// Let's display the progress in the activity title bar, like the
// browser app does.
getWindow().requestFeature(Window.FEATURE_PROGRESS);
WebView webview = new WebView(this);
setContentView(webview);
webview.getSettings().setJavaScriptEnabled(true);
final Activity activity = this;
webview.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
// Activities and WebViews measure progress with different scales.
// The progress meter will automatically disappear when we reach 100%
activity.setProgress(progress * 1000);
}
});
webview.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//Users will be notified in case there's an error (i.e. no internet connection)
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
});
CookieSyncManager.getInstance().startSync();
CookieSyncManager.getInstance().sync();
//This will load the webpage that we want to see
webview.loadUrl("http://");
}
}
You have to tell the CookieSyncManager to sync after it has loaded the page in question. In your sample code, the onCreate method executes completely before the WebView tries to load the page, so the sync process (which happens asynchronously) will probably complete before the page is loaded.
Instead, tell the CookieSyncManager to sync onPageFinished in the WebViewClient. That should get you what you want.
The CookieSyncManager Documentation is a good read for how to do this properly.
Here is how you could set up your WebViewClient implementation to do this for you:
webview.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//Users will be notified in case there's an error (i.e. no internet connection)
Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
public void onPageFinished(WebView view, String url) {
CookieSyncManager.getInstance().sync();
}
);
You would not need to tell the CookieSyncManager to sync elsewhere with this in place. I haven't tested this, so let me know if it works.
.sync() is to force a imediate sync ,and must be called after page load cause it sync RAM with cache , so cookie must be in ram before calling it .
System automatically sync it every 5 mintues if you use this scheme
onCreate:
CookieSyncManager.createInstance(context)
onResume:
CookieSyncManager.getInstance().startSync()
onPause:
CookieSyncManager.getInstance().stopSync()
I think you did not waited 5 mintues so system save cookie.
For those who are facing Problems with CookieManager class to make cookie persist even after closing the app, they should try the flush() function of CookieManager.
Please note that i haven't tried this, so if it works then please let me know too.
According to android documentation
void flush()
Ensures all cookies currently accessible through the getCookie API are written to persistent storage. This call will block the caller until it is done and may perform I/O.
Also in CookieSyncManager documnentation it is written that:
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(). CookieSyncManger link
Works perfectly for API 20+
myWebView.setWebViewClient(new WebViewClient(){
public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl){
Toast.makeText(MainActivity.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
}
public void onPageFinished(WebView webView, String url){
CookieManager.getInstance().flush();
}
}
);
Im trying the class WebView and have a few questions =) maybe you can help me
I have noticed that if you charge an single image in the webview, the webview resizes it to the screens width,but with multitouch you can make it smaller.
Is there any way of ignoring when the user attempts to make it smaller?
Can I know when the page finished the load?
and finally how can I save a full webpage for showing it to the user in offline mode?
Thanks so much in advance :D
Is there any way of ignoring when the user attempts to make it smaller?
Have a look at WebSettings.setSupportZoom()
Can I know when the page finished the load?
Configure a custom WebChromeClient as progress listener like this:
webview.setWebChromeClient(new WebChromeClient() {
#Override
public void onProgressChanged(WebView view, int progress)
{
if (progress == 100)
{
// do something
}
}
});
how can I save a full webpage for showing it to the user in offline mode?
Well, I'd like to know that as well, but I don't think its possible. For now I'm setting an aggressive cache mode (WebSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK)) and if my URL could not be loaded from cache, I load a locally available one from the resources:
final String urlToLoad = "http://www.my-url.com";
webview.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl)
{
if (urlToLoad.equals(failingUrl))
{
view.loadUrl("file:///android_res/raw/local_copy.html");
return;
}
super.onReceivedError(view, errorCode, description, failingUrl);
}
});
webview.loadUrl(urlToLoad);