diff --git a/packages/url_launcher/CHANGELOG.md b/packages/url_launcher/CHANGELOG.md index 20b64b11cd5f..ea0bf686f93c 100644 --- a/packages/url_launcher/CHANGELOG.md +++ b/packages/url_launcher/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.1.0 + +* Add `headers` field to enable headers in the Android implementation. + ## 5.0.5 * Add `enableDomStorage` field to `launch` to enable DOM storage in Android WebView. diff --git a/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java b/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java index 30d067664b85..b877a45bdb25 100644 --- a/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java +++ b/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java @@ -11,7 +11,9 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.provider.Browser; import android.view.KeyEvent; import android.webkit.WebResourceRequest; import android.webkit.WebView; @@ -21,6 +23,8 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.Registrar; +import java.util.HashMap; +import java.util.Map; /** UrlLauncherPlugin */ public class UrlLauncherPlugin implements MethodCallHandler { @@ -66,10 +70,12 @@ private void canLaunch(String url, Result result) { private void launch(MethodCall call, Result result, String url) { Intent launchIntent; - boolean useWebView = call.argument("useWebView"); - boolean enableJavaScript = call.argument("enableJavaScript"); - boolean enableDomStorage = call.argument("enableDomStorage"); - Activity activity = mRegistrar.activity(); + final boolean useWebView = call.argument("useWebView"); + final boolean enableJavaScript = call.argument("enableJavaScript"); + final boolean enableDomStorage = call.argument("enableDomStorage"); + final Map headersMap = call.argument("headers"); + final Activity activity = mRegistrar.activity(); + if (activity == null) { result.error("NO_ACTIVITY", "Launching a URL requires a foreground activity.", null); return; @@ -83,6 +89,10 @@ private void launch(MethodCall call, Result result, String url) { launchIntent = new Intent(Intent.ACTION_VIEW); launchIntent.setData(Uri.parse(url)); } + + final Bundle headersBundle = extractBundle(headersMap); + launchIntent.putExtra(Browser.EXTRA_HEADERS, headersBundle); + activity.startActivity(launchIntent); result.success(true); } @@ -93,6 +103,15 @@ private void closeWebView(Result result) { result.success(null); } + private Bundle extractBundle(Map headersMap) { + final Bundle headersBundle = new Bundle(); + for (String key : headersMap.keySet()) { + final String value = headersMap.get(key); + headersBundle.putString(key, value); + } + return headersBundle; + } + /* Launches WebView activity */ public static class WebViewActivity extends Activity { private WebView webview; @@ -104,23 +123,37 @@ public void onCreate(Bundle savedInstanceState) { webview = new WebView(this); setContentView(webview); // Get the Intent that started this activity and extract the string - Intent intent = getIntent(); - String url = intent.getStringExtra("url"); - Boolean enableJavaScript = intent.getBooleanExtra("enableJavaScript", false); - Boolean enableDomStorage = intent.getBooleanExtra("enableDomStorage", false); - webview.loadUrl(url); - if (enableJavaScript) { - webview.getSettings().setJavaScriptEnabled(enableJavaScript); - } - if (enableDomStorage) { - webview.getSettings().setDomStorageEnabled(enableDomStorage); - } + final Intent intent = getIntent(); + final String url = intent.getStringExtra("url"); + final boolean enableJavaScript = intent.getBooleanExtra("enableJavaScript", false); + final boolean enableDomStorage = intent.getBooleanExtra("enableDomStorage", false); + final Bundle headersBundle = intent.getBundleExtra(Browser.EXTRA_HEADERS); + + final Map headersMap = extractHeaders(headersBundle); + webview.loadUrl(url, headersMap); + + webview.getSettings().setJavaScriptEnabled(enableJavaScript); + webview.getSettings().setDomStorageEnabled(enableDomStorage); + // Open new urls inside the webview itself. webview.setWebViewClient( new WebViewClient() { + + @Override + @SuppressWarnings("deprecation") + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + view.loadUrl(url); + return false; + } + return super.shouldOverrideUrlLoading(view, url); + } + @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - view.loadUrl(request.getUrl().toString()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + view.loadUrl(request.getUrl().toString()); + } return false; } }); @@ -139,6 +172,15 @@ public void onReceive(Context arg0, Intent intent) { registerReceiver(broadcastReceiver, new IntentFilter("close")); } + private Map extractHeaders(Bundle headersBundle) { + final Map headersMap = new HashMap<>(); + for (String key : headersBundle.keySet()) { + final String value = headersBundle.getString(key); + headersMap.put(key, value); + } + return headersMap; + } + @Override protected void onDestroy() { super.onDestroy(); diff --git a/packages/url_launcher/example/lib/main.dart b/packages/url_launcher/example/lib/main.dart index 66b5e9f538e9..b4a7e4275bfc 100644 --- a/packages/url_launcher/example/lib/main.dart +++ b/packages/url_launcher/example/lib/main.dart @@ -38,7 +38,12 @@ class _MyHomePageState extends State { Future _launchInBrowser(String url) async { if (await canLaunch(url)) { - await launch(url, forceSafariVC: false, forceWebView: false); + await launch( + url, + forceSafariVC: false, + forceWebView: false, + headers: {'my_header_key': 'my_header_value'}, + ); } else { throw 'Could not launch $url'; } @@ -46,7 +51,12 @@ class _MyHomePageState extends State { Future _launchInWebViewOrVC(String url) async { if (await canLaunch(url)) { - await launch(url, forceSafariVC: true, forceWebView: true); + await launch( + url, + forceSafariVC: true, + forceWebView: true, + headers: {'my_header_key': 'my_header_value'}, + ); } else { throw 'Could not launch $url'; } @@ -112,7 +122,7 @@ class _MyHomePageState extends State { @override Widget build(BuildContext context) { - const String toLaunch = 'https://flutter.io'; + const String toLaunch = 'https://www.cylog.org/headers/'; return Scaffold( appBar: AppBar( title: Text(widget.title), diff --git a/packages/url_launcher/lib/url_launcher.dart b/packages/url_launcher/lib/url_launcher.dart index edae489b8dc0..045448fbde97 100644 --- a/packages/url_launcher/lib/url_launcher.dart +++ b/packages/url_launcher/lib/url_launcher.dart @@ -44,6 +44,7 @@ const MethodChannel _channel = MethodChannel('plugins.flutter.io/url_launcher'); /// javascript. /// [enableDomStorage] is an Android only setting. If true, WebView enable /// DOM storage. +/// [headers] is an Android only setting that adds headers to the WebView. /// /// Note that if any of the above are set to true but the URL is not a web URL, /// this will throw a [PlatformException]. @@ -61,6 +62,7 @@ Future launch( bool enableJavaScript, bool enableDomStorage, bool universalLinksOnly, + Map headers, Brightness statusBarBrightness, }) async { assert(urlString != null); @@ -91,6 +93,7 @@ Future launch( 'enableJavaScript': enableJavaScript ?? false, 'enableDomStorage': enableDomStorage ?? false, 'universalLinksOnly': universalLinksOnly ?? false, + 'headers': headers ?? {}, }, ); if (statusBarBrightness != null) { diff --git a/packages/url_launcher/pubspec.yaml b/packages/url_launcher/pubspec.yaml index 0c0711222338..864e803d5552 100644 --- a/packages/url_launcher/pubspec.yaml +++ b/packages/url_launcher/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL on Android and iOS. Supports web, phone, SMS, and email schemes. author: Flutter Team homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher -version: 5.0.5 +version: 5.1.0 flutter: plugin: diff --git a/packages/url_launcher/test/url_launcher_test.dart b/packages/url_launcher/test/url_launcher_test.dart index db746902f3d3..93f4acf71601 100644 --- a/packages/url_launcher/test/url_launcher_test.dart +++ b/packages/url_launcher/test/url_launcher_test.dart @@ -42,6 +42,28 @@ void main() { 'enableJavaScript': false, 'enableDomStorage': false, 'universalLinksOnly': false, + 'headers': {}, + }) + ], + ); + }); + + test('launch with headers', () async { + await launch( + 'http://example.com/', + headers: {'key': 'value'}, + ); + expect( + log, + [ + isMethodCall('launch', arguments: { + 'url': 'http://example.com/', + 'useSafariVC': true, + 'useWebView': false, + 'enableJavaScript': false, + 'enableDomStorage': false, + 'universalLinksOnly': false, + 'headers': {'key': 'value'}, }) ], ); @@ -59,6 +81,7 @@ void main() { 'enableJavaScript': false, 'enableDomStorage': false, 'universalLinksOnly': false, + 'headers': {}, }) ], ); @@ -77,6 +100,7 @@ void main() { 'enableJavaScript': false, 'enableDomStorage': false, 'universalLinksOnly': true, + 'headers': {}, }) ], ); @@ -94,6 +118,7 @@ void main() { 'enableJavaScript': false, 'enableDomStorage': false, 'universalLinksOnly': false, + 'headers': {}, }) ], ); @@ -112,6 +137,7 @@ void main() { 'enableJavaScript': true, 'enableDomStorage': false, 'universalLinksOnly': false, + 'headers': {}, }) ], ); @@ -130,6 +156,7 @@ void main() { 'enableJavaScript': false, 'enableDomStorage': true, 'universalLinksOnly': false, + 'headers': {}, }) ], ); @@ -147,6 +174,7 @@ void main() { 'enableJavaScript': false, 'enableDomStorage': false, 'universalLinksOnly': false, + 'headers': {}, }) ], );