Skip to content

android: add webview postMessage #188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ example/ios/Podfile.lock
**/Flutter/Generated.xcconfig/
**/Flutter/flutter_assets/

.settings
.classpath
.project
.vscode
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ flutterWebviewPlugin.launch(url,
- `Stream<String>` onUrlChanged
- `Stream<WebViewStateChanged>` onStateChanged
- `Stream<String>` onError
- `Stream<String>` onWebviewMessage

***Don't forget to dispose webview***
`flutterWebviewPlugin.dispose()`
Expand All @@ -111,7 +112,9 @@ Future<Null> launch(String url,
String userAgent: null,
bool withZoom: false,
bool withLocalStorage: true,
bool scrollBar: true});
bool scrollBar: true,
bool enableMessaging: false,
});
```
```dart
Future<String> evalJavascript(String code);
Expand All @@ -131,3 +134,7 @@ Future<Null> hide();
```dart
Future<Null> reloadUrl(String url);
```

```dart
Future<Null> linkBridge();
```
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.flutter_webview_plugin;


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
Expand Down Expand Up @@ -38,42 +37,48 @@ private FlutterWebviewPlugin(Activity activity) {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
switch (call.method) {
case "launch":
openUrl(call, result);
break;
case "close":
close(call, result);
break;
case "eval":
eval(call, result);
break;
case "resize":
resize(call, result);
break;
case "reload":
reload(call, result);
break;
case "back":
back(call, result);
break;
case "forward":
forward(call, result);
break;
case "hide":
hide(call, result);
break;
case "show":
show(call, result);
break;
case "reloadUrl":
reloadUrl(call, result);
break;
case "stopLoading":
stopLoading(call, result);
break;
default:
result.notImplemented();
break;
case "launch":
openUrl(call, result);
break;
case "close":
close(call, result);
break;
case "eval":
eval(call, result);
break;
case "resize":
resize(call, result);
break;
case "reload":
reload(call, result);
break;
case "back":
back(call, result);
break;
case "forward":
forward(call, result);
break;
case "hide":
hide(call, result);
break;
case "show":
show(call, result);
break;
case "reloadUrl":
reloadUrl(call, result);
break;
case "stopLoading":
stopLoading(call, result);
break;
case "postMessage":
postMessage(call, result);
break;
case "linkBridge":
linkBridge(call, result);
break;
default:
result.notImplemented();
break;
}
}

Expand All @@ -88,6 +93,7 @@ private void openUrl(MethodCall call, MethodChannel.Result result) {
boolean withLocalStorage = call.argument("withLocalStorage");
Map<String, String> headers = call.argument("headers");
boolean scrollBar = call.argument("scrollBar");
boolean enableMessaging = call.argument("enableMessaging");

if (webViewManager == null || webViewManager.closed == true) {
webViewManager = new WebviewManager(activity);
Expand All @@ -97,28 +103,19 @@ private void openUrl(MethodCall call, MethodChannel.Result result) {

activity.addContentView(webViewManager.webView, params);

webViewManager.openUrl(withJavascript,
clearCache,
hidden,
clearCookies,
userAgent,
url,
headers,
withZoom,
withLocalStorage,
scrollBar
);
webViewManager.openUrl(withJavascript, clearCache, hidden, clearCookies, userAgent, url, headers, withZoom,
withLocalStorage, scrollBar, enableMessaging);
result.success(null);
}

private FrameLayout.LayoutParams buildLayoutParams(MethodCall call) {
Map<String, Number> rc = call.argument("rect");
FrameLayout.LayoutParams params;
if (rc != null) {
params = new FrameLayout.LayoutParams(
dp2px(activity, rc.get("width").intValue()), dp2px(activity, rc.get("height").intValue()));
params.setMargins(dp2px(activity, rc.get("left").intValue()), dp2px(activity, rc.get("top").intValue()),
0, 0);
params = new FrameLayout.LayoutParams(dp2px(activity, rc.get("width").intValue()),
dp2px(activity, rc.get("height").intValue()));
params.setMargins(dp2px(activity, rc.get("left").intValue()), dp2px(activity, rc.get("top").intValue()), 0,
0);
} else {
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
Expand All @@ -132,7 +129,7 @@ private FrameLayout.LayoutParams buildLayoutParams(MethodCall call) {
}

private void stopLoading(MethodCall call, MethodChannel.Result result) {
if (webViewManager != null){
if (webViewManager != null) {
webViewManager.stopLoading(call, result);
}
}
Expand All @@ -144,47 +141,40 @@ private void close(MethodCall call, MethodChannel.Result result) {
}
}

/**
* Navigates back on the Webview.
*/
/**
* Navigates back on the Webview.
*/
private void back(MethodCall call, MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.back(call, result);
}
}
/**
* Navigates forward on the Webview.
*/

/**
* Navigates forward on the Webview.
*/
private void forward(MethodCall call, MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.forward(call, result);
}
}

/**
* Reloads the Webview.
*/
/**
* Reloads the Webview.
*/
private void reload(MethodCall call, MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.reload(call, result);
}
}

private void reloadUrl(MethodCall call, MethodChannel.Result result) {
if (webViewManager != null) {
String url = call.argument("url");
webViewManager.openUrl(false,
false,
false,
false,
"",
url,
null,
false,
false,
false
);
webViewManager.openUrl(false, false, false, false, "", url, null, false, false, false, false);
}
}

private void eval(MethodCall call, final MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.eval(call, result);
Expand All @@ -198,11 +188,13 @@ private void resize(MethodCall call, final MethodChannel.Result result) {
}
result.success(null);
}

private void hide(MethodCall call, final MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.hide(call, result);
}
}

private void show(MethodCall call, final MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.show(call, result);
Expand All @@ -216,9 +208,21 @@ private int dp2px(Context context, float dp) {

@Override
public boolean onActivityResult(int i, int i1, Intent intent) {
if(webViewManager != null && webViewManager.resultHandler != null){
if (webViewManager != null && webViewManager.resultHandler != null) {
return webViewManager.resultHandler.handleResult(i, i1, intent);
}
return false;
}

private void postMessage(MethodCall call, final MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.postMessage(call, result);
}
}

private void linkBridge(MethodCall call, final MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.linkBridge();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@

import static android.app.Activity.RESULT_OK;

import android.webkit.JavascriptInterface;
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by lejard_h on 20/12/2017.
*/
Expand All @@ -33,6 +38,7 @@ class WebviewManager {
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mUploadMessageArray;
private final static int FILECHOOSER_RESULTCODE=1;
private static final String CHANNEL_NAME = "flutter_webview_plugin";

@TargetApi(7)
class ResultHandler {
Expand Down Expand Up @@ -189,7 +195,7 @@ private void clearCache() {
webView.clearFormData();
}

void openUrl(boolean withJavascript, boolean clearCache, boolean hidden, boolean clearCookies, String userAgent, String url, Map<String, String> headers, boolean withZoom, boolean withLocalStorage, boolean scrollBar) {
void openUrl(boolean withJavascript, boolean clearCache, boolean hidden, boolean clearCookies, String userAgent, String url, Map<String, String> headers, boolean withZoom, boolean withLocalStorage, boolean scrollBar, boolean messagingEnabled) {
webView.getSettings().setJavaScriptEnabled(withJavascript);
webView.getSettings().setBuiltInZoomControls(withZoom);
webView.getSettings().setSupportZoom(withZoom);
Expand Down Expand Up @@ -220,6 +226,11 @@ void openUrl(boolean withJavascript, boolean clearCache, boolean hidden, boolean
} else {
webView.loadUrl(url);
}

if (messagingEnabled) {
enableMessaging();
}

}

void close(MethodCall call, MethodChannel.Result result) {
Expand Down Expand Up @@ -307,4 +318,60 @@ void stopLoading(MethodCall call, MethodChannel.Result result){
webView.stopLoading();
}
}

protected static class JsObject {
WebviewManager webviewManager;

JsObject(WebviewManager _webviewManager) {
webviewManager = _webviewManager;
}

@JavascriptInterface
public void postMessage(String message) {
webviewManager.onMessage(message);
}
}

public void onMessage(String message) {
FlutterWebviewPlugin.channel.invokeMethod("onWebviewMessage", message);
}

public void postMessage(MethodCall call, final MethodChannel.Result result) {
String message = call.argument("data");
try {
JSONObject eventInitDict = new JSONObject();
eventInitDict.put("data", message);
String script = "(function () {" +
"var event;" +
"var data = " + eventInitDict.toString() + ";" +
"try {" +
"event = new MessageEvent('message', data);" +
"} catch (e) {" +
"event = document.createEvent('MessageEvent');" +
"event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" +
"}" +
"document.dispatchEvent(event);" +
"})();";
webView.evaluateJavascript(script, null);

} catch (JSONException e) {
throw new RuntimeException(e);
}
}

protected void enableMessaging() {
webView.addJavascriptInterface(new JsObject(this), CHANNEL_NAME);
}


protected void linkBridge() {
String script = "(" +
"window.originalPostMessage = window.postMessage," +
"window.postMessage = function(data) {" +
CHANNEL_NAME + ".postMessage(String(data));" +
"}" +
")";

webView.evaluateJavascript(script, null);
}
}
Loading