Reputation: 3972
Android's WebKit does not implement all of the console APIs available in other desktop browsers. You can, however, use the basic text logging functions:
console.log(String) console.info(String) console.warn(String) console.error(String)
Other console functions don't raise errors, but might not behave the same as what you expect from other web browsers.
android.webkit.ConsoleMessage.MessageLevel:
ConsoleMessage.MessageLevel DEBUG
ConsoleMessage.MessageLevel ERROR
ConsoleMessage.MessageLevel LOG
ConsoleMessage.MessageLevel TIP
ConsoleMessage.MessageLevel WARNING
While Developing a webapp-native-hybrid especially for an Android-Device I was happy to be able to merge the JavaScript-console with the ordinary LogCat. But what a pity: there is a console.debug which results in MessageLevel.INFO and no console.verbose() at all (error get thrown).
Upvotes: 0
Views: 3282
Reputation: 3972
To solve this I would extend the functionality of the console with a simple (and really ugly and instable) adapter:
var c = window.console;
window.console = {
debug: function(message) { c.error("(DEBUG)#" + message); },
verbose: function(message) { c.error("(VERBOSE)#" + message); },
error: function(message) { c.error(message); },
warn: function(message) { c.warn(message); },
log: function(message) { c.log(message); },
info: function(message) { c.info(message); }
};
for (i in c) {
try {
window.console[c[i]]();
} catch(error) {
if(verbose) console.verbose("Funktion nicht implementiert: " + c[i]);
window.console[c[i]] = function(arguments) {
if(debug) console.debug("Aufruf nicht implementierter Funktion: " + this);
var funcDefArray = ("" + this).split(" ");
c[funcDefArray[1]](arguments);
};
}
}
This adapter provides the logging functions while adding a prefix (DEBUG)#
or (VERBOSE)#
to the message given as parameter and call error()
from original console object. Hopefully this will be the least used Level, so that's the place where to check the incoming messages for the prefix. The wished logging level of LogCat gets chosen by the extracted prefix:
public class CustomWebChromeClient extends WebChromeClient {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
String tag = TAG_JS;
StringBuffer message = new StringBuffer(consoleMessage.message());
MessageLevel lvl = consoleMessage.messageLevel();
if (lvl == MessageLevel.ERROR) {
int i = message.indexOf(")#");
if(i > 0 && i < 8) {
String realLevel = message.substring(1, i);
message.replace(0, i+2, "");
if("DEBUG".equals(realLevel)) lvl = MessageLevel.DEBUG;
else if("VERBOSE".equals(realLevel)) lvl = MessageLevel.TIP;
else tag += " (" + realLevel + ")";
} else {
String source = consoleMessage.sourceId();
source = source.substring(source.indexOf("/js/") + 1);
message.append(source);
message.append('(').append(consoleMessage.lineNumber()).append(')');
message.append(" –> ");
}
}
message.append(consoleMessage.message());
switch (lvl) {
case ERROR:
Log.e(tag, message.toString());
break;
case WARNING:
Log.w(tag, message.toString());
break;
case LOG:
Log.i(tag, message.toString());
break;
case DEBUG:
Log.d(tag, message.toString());
break;
case TIP:
Log.v(tag, message.toString());
break;
default:
Log.println(Log.ASSERT, tag, message.toString());
break;
}
return true;
}
}
I tried to manipulate the console functions by prototype, but at this time I'm not this familiar to get a working result right now. For my purposes it's enough and eventually someone other can use this crap.
If someone would provide me the few lines of prototyping I would be glad, and I hope that next time I need something like this I will be able to do it myself ;)
Upvotes: 2