Skip to content
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

Get the Android webview title #88

Closed
wants to merge 16 commits into from
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.flutter_webview_plugin;
import com.flutter_webview_plugin.OpenFileChooser;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by lejard_h on 20/12/2017.
*/

public class BrowserChromeClient extends WebChromeClient {

public final static int FILE_CHOOSER_RESULT_CODE = 10000;
OpenFileChooser activity;

public BrowserChromeClient(Activity activity) {
super();
this.activity = ((OpenFileChooser)activity);
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> valueCallback) {
activity.setUploadMessage(valueCallback);
openImageChooserActivity();
}

// For Android >= 3.0
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
activity.setUploadMessage(valueCallback);
openImageChooserActivity();
}

//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
activity.setUploadMessage(valueCallback);
openImageChooserActivity();
}

// For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
activity.setUploadMessageAboveL(filePathCallback);
openImageChooserActivity();
return true;
}
private void openImageChooserActivity() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
((Activity)activity).startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
package com.flutter_webview_plugin;

import android.graphics.Bitmap;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by lejard_h on 20/12/2017.
*/

public class BrowserClient extends WebViewClient {
public BrowserClient() {

private final List<String> mInterceptUrls;

public BrowserClient(List<String> interceptUrls) {
super();
mInterceptUrls = interceptUrls;
}

@Override
Expand All @@ -26,13 +32,24 @@ public void onPageStarted(WebView view, String url, Bitmap favicon) {
}

@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Map<String, Object> data = new HashMap<>();
data.put("url", url);

FlutterWebviewPlugin.channel.invokeMethod("onUrlChanged", data);
for (String interceptUrl : mInterceptUrls) {
if(url.contains(interceptUrl)){
return true;
}
}
return false;
}

@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Map<String, Object> data = new HashMap<>();
data.put("url", url);
data.put("type", "finishLoad");
FlutterWebviewPlugin.channel.invokeMethod("onState", data);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.view.Display;
import android.widget.FrameLayout;

import java.util.List;
import java.util.Map;

import io.flutter.plugin.common.MethodCall;
Expand Down Expand Up @@ -63,11 +64,16 @@ private void openUrl(MethodCall call, MethodChannel.Result result) {
boolean clearCookies = call.argument("clearCookies");
boolean withZoom = call.argument("withZoom");
boolean withLocalStorage = call.argument("withLocalStorage");
Map<String, String> additionalHttpHeaders = call.argument("additionalHttpHeaders");
List<String> interceptUrls = call.argument("interceptUrls");

if (webViewManager == null || webViewManager.closed == true) {
webViewManager = new WebviewManager(activity);
webViewManager = new WebviewManager(activity,interceptUrls);
}
if(webViewManager.webView.getParent() != null){
webViewManager.webView.loadUrl(url);
return;
}

FrameLayout.LayoutParams params = buildLayoutParams(call);

activity.addContentView(webViewManager.webView, params);
Expand All @@ -79,7 +85,8 @@ private void openUrl(MethodCall call, MethodChannel.Result result) {
userAgent,
url,
withZoom,
withLocalStorage
withLocalStorage,
additionalHttpHeaders
);
result.success(null);
}
Expand All @@ -106,8 +113,11 @@ private FrameLayout.LayoutParams buildLayoutParams(MethodCall call) {

private void close(MethodCall call, MethodChannel.Result result) {
if (webViewManager != null) {
webViewManager.close(call, result);
webViewManager = null;
boolean goBack = call.argument("goBack");
webViewManager.close(goBack, result);
if(!goBack){
webViewManager = null;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.flutter_webview_plugin;

import android.webkit.ValueCallback;

/**
* Created by lejard_h on 20/12/2017.
*/
public interface OpenFileChooser {
void setUploadMessage(ValueCallback valueCallback);
void setUploadMessageAboveL(ValueCallback valueCallback);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.*;
import android.widget.FrameLayout;

import com.flutter_webview_plugin.BrowserChromeClient;
import com.flutter_webview_plugin.BrowserClient;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;

import java.util.List;
import java.util.Map;

/**
* Created by lejard_h on 20/12/2017.
*/
Expand All @@ -25,9 +26,9 @@ class WebviewManager {
boolean closed = false;
WebView webView;

WebviewManager(Activity activity) {
WebviewManager(Activity activity, List<String> interceptUrls) {
this.webView = new WebView(activity);
WebViewClient webViewClient = new BrowserClient();
WebViewClient webViewClient = new BrowserClient(interceptUrls);
webView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
Expand All @@ -46,8 +47,12 @@ public boolean onKey(View v, int keyCode, KeyEvent event) {
return false;
}
});

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webView.setWebViewClient(webViewClient);
WebChromeClient webChromeClient= new BrowserChromeClient(activity);
webView.setWebChromeClient(webChromeClient);
}

private void clearCookies() {
Expand All @@ -68,12 +73,13 @@ private void clearCache() {
webView.clearFormData();
}

void openUrl(boolean withJavascript, boolean clearCache, boolean hidden, boolean clearCookies, String userAgent, String url, boolean withZoom, boolean withLocalStorage) {
void openUrl(boolean withJavascript, boolean clearCache, boolean hidden, boolean clearCookies, String userAgent, String url, boolean withZoom, boolean withLocalStorage, Map<String, String> additionalHttpHeaders) {
webView.getSettings().setJavaScriptEnabled(withJavascript);
webView.getSettings().setBuiltInZoomControls(withZoom);
webView.getSettings().setSupportZoom(withZoom);
webView.getSettings().setDomStorageEnabled(withLocalStorage);

webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
if (clearCache) {
clearCache();
}
Expand All @@ -90,25 +96,28 @@ void openUrl(boolean withJavascript, boolean clearCache, boolean hidden, boolean
webView.getSettings().setUserAgentString(userAgent);
}

webView.loadUrl(url);
webView.loadUrl(url, additionalHttpHeaders);
}

void close(MethodCall call, MethodChannel.Result result) {
if (webView != null) {
ViewGroup vg = (ViewGroup) (webView.getParent());
vg.removeView(webView);
}
webView = null;
if (result != null) {
result.success(null);
void close(boolean goBack, MethodChannel.Result result) {
if(goBack && webView.canGoBack()){
webView.goBack();
}else {
if (webView != null) {
ViewGroup vg = (ViewGroup) (webView.getParent());
vg.removeView(webView);
}
webView = null;
if (result != null) {
result.success(null);
}
closed = true;
FlutterWebviewPlugin.channel.invokeMethod("onDestroy", null);
}

closed = true;
FlutterWebviewPlugin.channel.invokeMethod("onDestroy", null);
}

void close() {
close(null, null);
close(false, null);
}

@TargetApi(Build.VERSION_CODES.KITKAT)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
9 changes: 7 additions & 2 deletions ios/Classes/FlutterWebviewPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@interface FlutterWebviewPlugin() <WKNavigationDelegate, UIScrollViewDelegate> {
BOOL _enableAppScheme;
BOOL _enableZoom;
NSMutableDictionary *_additionalHttpHeaders;
}
@end

Expand All @@ -25,6 +26,7 @@ - (instancetype)initWithViewController:(UIViewController *)viewController {
self = [super init];
if (self) {
self.viewController = viewController;
_additionalHttpHeaders = [[NSMutableDictionary alloc] init];
}
return self;
}
Expand Down Expand Up @@ -57,6 +59,7 @@ - (void)initWebview:(FlutterMethodCall*)call {
NSNumber *hidden = call.arguments[@"hidden"];
NSDictionary *rect = call.arguments[@"rect"];
_enableAppScheme = call.arguments[@"enableAppScheme"];
_additionalHttpHeaders = call.arguments[@"additionalHttpHeaders"];
NSString *userAgent = call.arguments[@"userAgent"];
NSNumber *withZoom = call.arguments[@"withZoom"];

Expand Down Expand Up @@ -102,7 +105,10 @@ - (CGRect)parseRect:(NSDictionary *)rect {
- (void)navigate:(FlutterMethodCall*)call {
if (self.webview != nil) {
NSString *url = call.arguments[@"url"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
for (NSString *key in _additionalHttpHeaders) {
[request setValue:_additionalHttpHeaders[key] forHTTPHeaderField:key];
}
[self.webview loadRequest:request];
}
}
Expand Down Expand Up @@ -155,7 +161,6 @@ - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigati
id data = @{@"url": navigationAction.request.URL.absoluteString};
[channel invokeMethod:@"onUrlChanged" arguments:data];
}

if (_enableAppScheme ||
([webView.URL.scheme isEqualToString:@"http"] ||
[webView.URL.scheme isEqualToString:@"https"] ||
Expand Down
11 changes: 8 additions & 3 deletions lib/src/base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ class FlutterWebviewPlugin {
Rect rect,
String userAgent,
bool withZoom,
bool withLocalStorage}) async {
bool withLocalStorage,
Map<String,String> additionalHttpHeaders,
List<String> interceptUrls,
}) async {
Map<String, dynamic> args = {
"url": url,
"withJavascript": withJavascript ?? true,
Expand All @@ -90,7 +93,9 @@ class FlutterWebviewPlugin {
"enableAppScheme": enableAppScheme ?? true,
"userAgent": userAgent,
"withZoom": withZoom ?? false,
"withLocalStorage": withLocalStorage ?? true
"withLocalStorage": withLocalStorage ?? true,
"additionalHttpHeaders": additionalHttpHeaders ?? {},
"interceptUrls": interceptUrls ?? []
};
if (rect != null) {
args["rect"] = {
Expand All @@ -111,7 +116,7 @@ class FlutterWebviewPlugin {

/// Close the Webview
/// Will trigger the [onDestroy] event
Future close() => _channel.invokeMethod("close");
Future close([bool goBack = false]) => _channel.invokeMethod("close",{'goBack':goBack});

/// Close all Streams
void dispose() {
Expand Down
Loading