How to Clear the (Css) Visited History of an Android Webview

How to clear the (CSS) visited history of an Android WebView?

Override WebChromeClient and WebViewClient... Damn that was hidden.

I actually had to dig up a bit to find this out.

WebView webView = (WebView)findViewById(R.id.myWebView);
WebChromeClient myWebChromeClient = new WebChromeClient(){
@Override
public void getVisitedHistory(ValueCallback<String[]> callback) {
// called during webview initialization, original implementation does strictly nothing
// and defaults to the native method WebViewCore.nativeProvideVisitedHistory()
String[] myUserHistory = getVisitedUrlsFromMyOwnDatabase(userId);
callback.onReceiveValue(myUserHistory);
}
};
WebViewClient myWebViewClient = new WebViewClient(){
@Override
public void doUpdateVisitedHistory(WebView view, String url,
boolean isReload) {
// called whenever there is a new link being visited
insertIfNotExistVisitedUrlIntoMyOwnDatabaseForUser(userId);
super(view, url, isReload);
}
}
webView.setWebViewClient(myWebViewClient);
webView.setChromeClient(myWebChromeClient);
webView.getSettings().etc(whatever)...

I think I'm "almost there". Here's the part I managed: what it does so far is remove css history altogether, so we're halfway there. I can't get the browser to recognize the url format I'm providing in "myUserHistory", so in effect the only feature this code does is reset css history altogether, but it's only called once when the WebView is instanciated (or created, didn't check), so for a true multiuser experience you'd need to recreate the webview at each login.

My problem now is that I can't manage to load the urlHistory properly. My Honeycomb Xoom webview seems to ignore my data.
Ah well, I hope it works for you. For me just calling callback.onReceiveValue(new String[]{}); in getVisitedHistory() will be good enough.

EDIT:
I just put twenty more minutes into it because I'm curious. This method is what delegates to the WebChromeClient (mCallbackProxy = WebChromeClient).

protected void populateVisitedLinks() {
ValueCallback callback = new ValueCallback<String[]>() {
public void onReceiveValue(String[] value) {
sendMessage(EventHub.POPULATE_VISITED_LINKS, (Object)value);
}
};
mCallbackProxy.getVisitedHistory(callback);
}

It's protected in WebViewCore, which is a private attribute of WebView with no accessor. The sendMessage delegates to EventHub which is private, and WebViewCore is filled with private native methods, and one of these seems to be the one actually calling the populateVisitedLinks() method during the initialization.

Unless someone at Google adds a public method to WebView to trigger the repopulation, I'm afraid it's practically impossible to achieve your goal. Sorry :(

As a side note, all these native visited history handling really makes me wonder: why do hardware manufacturers care so much about which urls we visited? ;) <<< sarcasm

Android Webview - Completely Clear the Cache

The edited code snippet above posted by Gaunt Face contains an error in that if a directory fails to delete because one of its files cannot be deleted, the code will keep retrying in an infinite loop. I rewrote it to be truly recursive, and added a numDays parameter so you can control how old the files must be that are pruned:

//helper method for clearCache() , recursive
//returns number of deleted files
static int clearCacheFolder(final File dir, final int numDays) {

int deletedFiles = 0;
if (dir!= null && dir.isDirectory()) {
try {
for (File child:dir.listFiles()) {

//first delete subdirectories recursively
if (child.isDirectory()) {
deletedFiles += clearCacheFolder(child, numDays);
}

//then delete the files and subdirectories in this dir
//only empty directories can be deleted, so subdirs have been done first
if (child.lastModified() < new Date().getTime() - numDays * DateUtils.DAY_IN_MILLIS) {
if (child.delete()) {
deletedFiles++;
}
}
}
}
catch(Exception e) {
Log.e(TAG, String.format("Failed to clean the cache, error %s", e.getMessage()));
}
}
return deletedFiles;
}

/*
* Delete the files older than numDays days from the application cache
* 0 means all files.
*/
public static void clearCache(final Context context, final int numDays) {
Log.i(TAG, String.format("Starting cache prune, deleting files older than %d days", numDays));
int numDeletedFiles = clearCacheFolder(context.getCacheDir(), numDays);
Log.i(TAG, String.format("Cache pruning completed, %d files deleted", numDeletedFiles));
}

Hopefully of use to other people :)

goBack() in WebView goes back ALMOST all the way

After rebuilding the activity from the example in the docs, I still got the problem. And also, sometimes it would stop loading after a few lines of html and sometimes after half a screenful.

A single line in the valid CSS for the start page caused the rendering to break without any error message. The page worked fine in Chrome on the same phone, which points to the implementation of WebViews being incomplete in comparison.

Thanks to people answering and sorry for the time wasted. It's just too bad to follow the standards, program correctly, and have bugs trip you up and make a project negatively profitable.

If the Google devs want to patch this or at least trigger an error, the offending line was span:empty {display:none;}

Detect if user is using webview for android/iOS or a regular browser

Detecting browser for iOS devices is different from the Android one. For iOS devices you can do it by checking user agent using JavaScript:

var userAgent = window.navigator.userAgent.toLowerCase(),
safari = /safari/.test( userAgent ),
ios = /iphone|ipod|ipad/.test( userAgent );

if( ios ) {
if ( safari ) {
//browser
} else if ( !safari ) {
//webview
};
} else {
//not iOS
};

For Android devices, you need to do it through server side coding to check for a request header.

PHP:

if ($_SERVER['HTTP_X_REQUESTED_WITH'] == "your.app.id") {
//webview
} else {
//browser
}

JSP:

if ("your.app.id".equals(req.getHeader("X-Requested-With")) ){
//webview
} else {
//browser
}

Ref:detect ipad/iphone webview via javascript



Related Topics



Leave a reply



Submit