001.
private
class
GingerbreadWebViewClient
extends
WebViewClient {
002.
private
Object jsInterface;
003.
private
String jsInterfaceName;
004.
private
String jsSignature;
005.
006.
public
GingerbreadWebViewClient(Object jsInterface, String jsInterfaceName, String jsSignature) {
007.
this
.jsInterface = jsInterface;
008.
this
.jsInterfaceName = jsInterfaceName;
009.
this
.jsSignature = jsSignature;
010.
}
011.
012.
013.
@Override
014.
public
void
onPageFinished(WebView view, String url) {
015.
super
.onPageFinished(view, url);
016.
017.
if
(javascriptInterfaceBroken) {
018.
StringBuilder gbjs =
new
StringBuilder();
019.
020.
gbjs.append(
"javascript: "
);
021.
gbjs.append(generateJS());
022.
023.
view.loadUrl(gbjs.toString());
024.
}
025.
026.
027.
view.loadUrl(
"javascript: android_init();"
);
028.
}
029.
030.
031.
032.
033.
034.
035.
036.
037.
public
String generateJS() {
038.
StringBuilder gbjs =
new
StringBuilder();
039.
040.
if
(javascriptInterfaceBroken) {
041.
StringBuilder sb;
042.
043.
gbjs.append(
"var "
); gbjs.append(jsInterfaceName); gbjs.append(
" = { "
+
044.
" _gbFix: function(fxname, xargs) {"
+
045.
" var args = new Array();"
+
046.
" for (var i = 0; i < xargs.length; i++) {"
+
047.
" args.push(xargs[i].toString());"
+
048.
" };"
+
049.
" var data = { name: fxname, len: args.length, args: args };"
+
050.
" var json = JSON.stringify(data);"
+
051.
" var res = prompt('"
); gbjs.append(jsSignature); gbjs.append(
"' + json);"
+
052.
" return JSON.parse(res)['result'];"
+
053.
" }"
+
054.
"};"
);
055.
056.
057.
for
(Method m : jsInterface.getClass().getMethods()) {
058.
sb =
new
StringBuilder();
059.
060.
061.
sb.append(jsInterfaceName);
062.
sb.append(
"."
);
063.
sb.append(m.getName());
064.
sb.append(
" = function() { return this._gbFix('"
);
065.
sb.append(m.getName());
066.
sb.append(
"', arguments); };"
);
067.
068.
gbjs.append(sb);
069.
}
070.
}
071.
072.
return
gbjs.toString();
073.
}
074.
}
075.
076.
077.
private
class
GingerbreadWebViewChrome
extends
WebChromeClient {
078.
private
Object jsInterface;
079.
private
String jsSignature;
080.
081.
082.
public
GingerbreadWebViewChrome(Object jsInterface, String jsSignature) {
083.
this
.jsInterface = jsInterface;
084.
this
.jsSignature = jsSignature;
085.
}
086.
087.
088.
@Override
089.
public
boolean
onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
090.
if
(!javascriptInterfaceBroken || TextUtils.isEmpty(message) || !message.startsWith(jsSignature)) {
091.
return
false
;
092.
}
093.
094.
095.
JSONObject jsonData;
096.
String functionName;
097.
String encodedData;
098.
099.
try
{
100.
encodedData = message.substring(jsSignature.length());
101.
jsonData =
new
JSONObject(encodedData);
102.
encodedData =
null
;
103.
functionName = jsonData.getString(
"name"
);
104.
105.
for
(Method m : jsInterface.getClass().getMethods()) {
106.
if
(m.getName().equals(functionName)) {
107.
JSONArray jsonArgs = jsonData.getJSONArray(
"args"
);
108.
Object[] args =
new
Object[jsonArgs.length()];
109.
110.
for
(
int
i =
0
; i < jsonArgs.length(); i++) {
111.
args[i] = jsonArgs.get(i);
112.
}
113.
114.
Object ret = m.invoke(jsInterface, args);
115.
JSONObject res =
new
JSONObject();
116.
res.put(
"result"
, ret);
117.
result.confirm(res.toString());
118.
return
true
;
119.
}
120.
}
121.
122.
123.
throw
new
RuntimeException(
"shouldOverrideUrlLoading: Could not find method '"
+ functionName +
"()'."
);
124.
}
125.
catch
(IllegalArgumentException e) {
126.
Log.e(
"GingerbreadWebViewClient"
,
"shouldOverrideUrlLoading: Please ensure your JSInterface methods only have String as parameters."
);
127.
throw
new
RuntimeException(e);
128.
}
129.
catch
(IllegalAccessException e) {
130.
throw
new
RuntimeException(e);
131.
}
132.
catch
(InvocationTargetException e) {
133.
throw
new
RuntimeException(e);
134.
}
135.
catch
(JSONException e) {
136.
e.printStackTrace();
137.
throw
new
RuntimeException(e);
138.
}
139.
}
140.
}