fix #1152
This commit is contained in:
parent
07768cdc81
commit
e07ba2a675
|
@ -1,3 +1,7 @@
|
||||||
|
## 5.4.2
|
||||||
|
|
||||||
|
- Added `setActionButton` method to `ChromeSafariBrowser` class
|
||||||
|
|
||||||
## 5.4.1+2
|
## 5.4.1+2
|
||||||
|
|
||||||
- Fixed "Android ServiceWorkerControllerCompat.setServiceWorkerClient(null) makes Webivew Plugin Crashes" [#1151](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1151)
|
- Fixed "Android ServiceWorkerControllerCompat.setServiceWorkerClient(null) makes Webivew Plugin Crashes" [#1151](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1151)
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class ActionBroadcastReceiver extends BroadcastReceiver {
|
||||||
obj.put("url", url);
|
obj.put("url", url);
|
||||||
obj.put("title", title);
|
obj.put("title", title);
|
||||||
obj.put("id", id);
|
obj.put("id", id);
|
||||||
channel.invokeMethod("onChromeSafariBrowserMenuItemActionPerform", obj);
|
channel.invokeMethod("onChromeSafariBrowserItemActionPerform", obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,14 @@ package com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.browser.customtabs.CustomTabColorSchemeParams;
|
import androidx.browser.customtabs.CustomTabColorSchemeParams;
|
||||||
import androidx.browser.customtabs.CustomTabsCallback;
|
import androidx.browser.customtabs.CustomTabsCallback;
|
||||||
import androidx.browser.customtabs.CustomTabsIntent;
|
import androidx.browser.customtabs.CustomTabsIntent;
|
||||||
|
@ -16,7 +18,10 @@ import androidx.browser.customtabs.CustomTabsService;
|
||||||
import androidx.browser.customtabs.CustomTabsSession;
|
import androidx.browser.customtabs.CustomTabsSession;
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsActionButton;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsMenuItem;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -37,6 +42,10 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
protected boolean onChromeSafariBrowserOpened = false;
|
protected boolean onChromeSafariBrowserOpened = false;
|
||||||
protected boolean onChromeSafariBrowserCompletedInitialLoad = false;
|
protected boolean onChromeSafariBrowserCompletedInitialLoad = false;
|
||||||
public ChromeSafariBrowserManager manager;
|
public ChromeSafariBrowserManager manager;
|
||||||
|
public String initialUrl;
|
||||||
|
public List<CustomTabsMenuItem> menuItems = new ArrayList<>();
|
||||||
|
@Nullable
|
||||||
|
public CustomTabsActionButton actionButton;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
@ -55,20 +64,23 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
channel = new MethodChannel(manager.plugin.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + id);
|
channel = new MethodChannel(manager.plugin.messenger, "com.pichillilorenzo/flutter_chromesafaribrowser_" + id);
|
||||||
channel.setMethodCallHandler(this);
|
channel.setMethodCallHandler(this);
|
||||||
|
|
||||||
final String url = b.getString("url");
|
initialUrl = b.getString("url");
|
||||||
|
|
||||||
options = new ChromeCustomTabsOptions();
|
options = new ChromeCustomTabsOptions();
|
||||||
options.parse((HashMap<String, Object>) b.getSerializable("options"));
|
options.parse((Map<String, Object>) b.getSerializable("options"));
|
||||||
|
actionButton = CustomTabsActionButton.fromMap((Map<String, Object>) b.getSerializable("actionButton"));
|
||||||
final List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) b.getSerializable("menuItemList");
|
List<Map<String, Object>> menuItemList = (List<Map<String, Object>>) b.getSerializable("menuItemList");
|
||||||
|
for (Map<String, Object> menuItem : menuItemList) {
|
||||||
|
menuItems.add(CustomTabsMenuItem.fromMap(menuItem));
|
||||||
|
}
|
||||||
|
|
||||||
final ChromeCustomTabsActivity chromeCustomTabsActivity = this;
|
final ChromeCustomTabsActivity chromeCustomTabsActivity = this;
|
||||||
|
|
||||||
customTabActivityHelper = new CustomTabActivityHelper();
|
customTabActivityHelper = new CustomTabActivityHelper();
|
||||||
customTabActivityHelper.setConnectionCallback(new CustomTabActivityHelper.ConnectionCallback() {
|
customTabActivityHelper.setConnectionCallback(new CustomTabActivityHelper.ConnectionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onCustomTabsConnected() {
|
public void onCustomTabsConnected() {
|
||||||
customTabsConnected(url, menuItemList);
|
customTabsConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -140,13 +152,13 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void customTabsConnected (String url, List<HashMap<String, Object>> menuItemList) {
|
public void customTabsConnected() {
|
||||||
customTabsSession = customTabActivityHelper.getSession();
|
customTabsSession = customTabActivityHelper.getSession();
|
||||||
Uri uri = Uri.parse(url);
|
Uri uri = Uri.parse(initialUrl);
|
||||||
customTabActivityHelper.mayLaunchUrl(uri, null, null);
|
customTabActivityHelper.mayLaunchUrl(uri, null, null);
|
||||||
|
|
||||||
builder = new CustomTabsIntent.Builder(customTabsSession);
|
builder = new CustomTabsIntent.Builder(customTabsSession);
|
||||||
prepareCustomTabs(menuItemList);
|
prepareCustomTabs();
|
||||||
|
|
||||||
CustomTabsIntent customTabsIntent = builder.build();
|
CustomTabsIntent customTabsIntent = builder.build();
|
||||||
prepareCustomTabsIntent(customTabsIntent);
|
prepareCustomTabsIntent(customTabsIntent);
|
||||||
|
@ -154,7 +166,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
CustomTabActivityHelper.openCustomTab(this, customTabsIntent, uri, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
CustomTabActivityHelper.openCustomTab(this, customTabsIntent, uri, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCustomTabs(List<HashMap<String, Object>> menuItemList) {
|
private void prepareCustomTabs() {
|
||||||
if (options.addDefaultShareMenuItem != null) {
|
if (options.addDefaultShareMenuItem != null) {
|
||||||
builder.setShareState(options.addDefaultShareMenuItem ?
|
builder.setShareState(options.addDefaultShareMenuItem ?
|
||||||
CustomTabsIntent.SHARE_STATE_ON : CustomTabsIntent.SHARE_STATE_OFF);
|
CustomTabsIntent.SHARE_STATE_ON : CustomTabsIntent.SHARE_STATE_OFF);
|
||||||
|
@ -173,10 +185,21 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
||||||
builder.setUrlBarHidingEnabled(options.enableUrlBarHiding);
|
builder.setUrlBarHidingEnabled(options.enableUrlBarHiding);
|
||||||
builder.setInstantAppsEnabled(options.instantAppsEnabled);
|
builder.setInstantAppsEnabled(options.instantAppsEnabled);
|
||||||
|
|
||||||
for (HashMap<String, Object> menuItem : menuItemList) {
|
for (CustomTabsMenuItem menuItem : menuItems) {
|
||||||
int id = (int) menuItem.get("id");
|
builder.addMenuItem(menuItem.getLabel(),
|
||||||
String label = (String) menuItem.get("label");
|
createPendingIntent(menuItem.getId()));
|
||||||
builder.addMenuItem(label, createPendingIntent(id));
|
}
|
||||||
|
|
||||||
|
if (actionButton != null) {
|
||||||
|
byte[] data = actionButton.getIcon();
|
||||||
|
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
|
||||||
|
bitmapOptions.inMutable = true;
|
||||||
|
Bitmap bmp = BitmapFactory.decodeByteArray(
|
||||||
|
data, 0, data.length, bitmapOptions
|
||||||
|
);
|
||||||
|
builder.setActionButton(bmp, actionButton.getDescription(),
|
||||||
|
createPendingIntent(actionButton.getId()),
|
||||||
|
actionButton.isShouldTint());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,22 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
||||||
|
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
case "open":
|
case "open":
|
||||||
{
|
if (plugin != null) {
|
||||||
String url = (String) call.argument("url");
|
String url = (String) call.argument("url");
|
||||||
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
|
HashMap<String, Object> options = (HashMap<String, Object>) call.argument("options");
|
||||||
|
HashMap<String, Object> actionButton = (HashMap<String, Object>) call.argument("actionButton");
|
||||||
List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) call.argument("menuItemList");
|
List<HashMap<String, Object>> menuItemList = (List<HashMap<String, Object>>) call.argument("menuItemList");
|
||||||
open(plugin.activity, id, url, options, menuItemList, result);
|
open(plugin.activity, id, url, options, actionButton, menuItemList, result);
|
||||||
|
} else {
|
||||||
|
result.success(false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "isAvailable":
|
case "isAvailable":
|
||||||
result.success(CustomTabActivityHelper.isAvailable(plugin.activity));
|
if (plugin != null) {
|
||||||
|
result.success(CustomTabActivityHelper.isAvailable(plugin.activity));
|
||||||
|
} else {
|
||||||
|
result.success(false);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
|
@ -57,6 +64,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
||||||
}
|
}
|
||||||
|
|
||||||
public void open(Activity activity, String id, String url, HashMap<String, Object> options,
|
public void open(Activity activity, String id, String url, HashMap<String, Object> options,
|
||||||
|
HashMap<String, Object> actionButton,
|
||||||
List<HashMap<String, Object>> menuItemList, MethodChannel.Result result) {
|
List<HashMap<String, Object>> menuItemList, MethodChannel.Result result) {
|
||||||
|
|
||||||
Intent intent = null;
|
Intent intent = null;
|
||||||
|
@ -66,6 +74,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
||||||
extras.putString("id", id);
|
extras.putString("id", id);
|
||||||
extras.putString("managerId", this.id);
|
extras.putString("managerId", this.id);
|
||||||
extras.putSerializable("options", options);
|
extras.putSerializable("options", options);
|
||||||
|
extras.putSerializable("actionButton", (Serializable) actionButton);
|
||||||
extras.putSerializable("menuItemList", (Serializable) menuItemList);
|
extras.putSerializable("menuItemList", (Serializable) menuItemList);
|
||||||
|
|
||||||
Boolean isSingleInstance = (Boolean) Util.getOrDefault(options, "isSingleInstance", false);
|
Boolean isSingleInstance = (Boolean) Util.getOrDefault(options, "isSingleInstance", false);
|
||||||
|
|
|
@ -18,9 +18,9 @@ public class TrustedWebActivity extends ChromeCustomTabsActivity {
|
||||||
public TrustedWebActivityIntentBuilder builder;
|
public TrustedWebActivityIntentBuilder builder;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void customTabsConnected (String url, List<HashMap<String, Object>> menuItemList) {
|
public void customTabsConnected() {
|
||||||
customTabsSession = customTabActivityHelper.getSession();
|
customTabsSession = customTabActivityHelper.getSession();
|
||||||
Uri uri = Uri.parse(url);
|
Uri uri = Uri.parse(initialUrl);
|
||||||
customTabActivityHelper.mayLaunchUrl(uri, null, null);
|
customTabActivityHelper.mayLaunchUrl(uri, null, null);
|
||||||
|
|
||||||
builder = new TrustedWebActivityIntentBuilder(uri);
|
builder = new TrustedWebActivityIntentBuilder(uri);
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CustomTabsActionButton {
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private byte[] icon;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private boolean shouldTint;
|
||||||
|
|
||||||
|
public CustomTabsActionButton(int id, @NonNull byte[] icon, @NonNull String description, boolean shouldTint) {
|
||||||
|
this.id = id;
|
||||||
|
this.icon = icon;
|
||||||
|
this.description = description;
|
||||||
|
this.shouldTint = shouldTint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static CustomTabsActionButton fromMap(@Nullable Map<String, Object> map) {
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int id = (int) map.get("id");
|
||||||
|
byte[] icon = (byte[]) map.get("icon");
|
||||||
|
String description = (String) map.get("description");
|
||||||
|
boolean shouldTint = (boolean) map.get("shouldTint");
|
||||||
|
return new CustomTabsActionButton(id, icon, description, shouldTint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public byte[] getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIcon(@NonNull byte[] icon) {
|
||||||
|
this.icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(@NonNull String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShouldTint() {
|
||||||
|
return shouldTint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShouldTint(boolean shouldTint) {
|
||||||
|
this.shouldTint = shouldTint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
CustomTabsActionButton that = (CustomTabsActionButton) o;
|
||||||
|
|
||||||
|
if (id != that.id) return false;
|
||||||
|
if (shouldTint != that.shouldTint) return false;
|
||||||
|
if (!Arrays.equals(icon, that.icon)) return false;
|
||||||
|
return description.equals(that.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = id;
|
||||||
|
result = 31 * result + Arrays.hashCode(icon);
|
||||||
|
result = 31 * result + description.hashCode();
|
||||||
|
result = 31 * result + (shouldTint ? 1 : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CustomTabsActionButton{" +
|
||||||
|
"id=" + id +
|
||||||
|
", icon=" + Arrays.toString(icon) +
|
||||||
|
", description='" + description + '\'' +
|
||||||
|
", shouldTint=" + shouldTint +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CustomTabsMenuItem {
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String label;
|
||||||
|
|
||||||
|
public CustomTabsMenuItem(int id, @NonNull String label) {
|
||||||
|
this.id = id;
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static CustomTabsMenuItem fromMap(@Nullable Map<String, Object> map) {
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
int id = (int) map.get("id");
|
||||||
|
String label = (String) map.get("label");
|
||||||
|
return new CustomTabsMenuItem(id, label);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(@NonNull String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
CustomTabsMenuItem that = (CustomTabsMenuItem) o;
|
||||||
|
|
||||||
|
if (id != that.id) return false;
|
||||||
|
return label.equals(that.label);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = id;
|
||||||
|
result = 31 * result + label.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CustomTabsMenuItem{" +
|
||||||
|
"id=" + id +
|
||||||
|
", label='" + label + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -4148,7 +4148,7 @@ setTimeout(function() {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
await pageLoaded.future;
|
await pageLoaded.future;
|
||||||
expect(await controller.evaluateJavascript(source: "document.body"),
|
expect(await controller.evaluateJavascript(source: "document.body"),
|
||||||
isNull);
|
isEmpty);
|
||||||
} else if (Platform.isIOS) {
|
} else if (Platform.isIOS) {
|
||||||
expect(pageLoaded.future, doesNotComplete);
|
expect(pageLoaded.future, doesNotComplete);
|
||||||
}
|
}
|
||||||
|
@ -5847,7 +5847,57 @@ setTimeout(function() {
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('add custom menu item', () async {
|
||||||
|
var chromeSafariBrowser = new MyChromeSafariBrowser();
|
||||||
|
chromeSafariBrowser.addMenuItem(ChromeSafariBrowserMenuItem(
|
||||||
|
id: 2,
|
||||||
|
label: 'Custom item menu 1',
|
||||||
|
action: (url, title) {
|
||||||
|
print('Custom item menu 1 clicked!');
|
||||||
|
}));
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
|
await chromeSafariBrowser.open(
|
||||||
|
url: Uri.parse("https://github.com/flutter"));
|
||||||
|
await chromeSafariBrowser.browserCreated.future;
|
||||||
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
|
expect(() async {
|
||||||
|
await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev"));
|
||||||
|
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
||||||
|
|
||||||
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
|
await chromeSafariBrowser.close();
|
||||||
|
await chromeSafariBrowser.browserClosed.future;
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
});
|
||||||
|
|
||||||
group('Android Custom Tabs', () {
|
group('Android Custom Tabs', () {
|
||||||
|
test('add custom action button', () async {
|
||||||
|
var chromeSafariBrowser = new MyChromeSafariBrowser();
|
||||||
|
var actionButtonIcon = await rootBundle.load('test_assets/images/flutter-logo.png');
|
||||||
|
chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton(
|
||||||
|
id: 1,
|
||||||
|
description: 'Action Button description',
|
||||||
|
icon: actionButtonIcon.buffer.asUint8List(),
|
||||||
|
action: (url, title) {
|
||||||
|
print('Action Button 1 clicked!');
|
||||||
|
}));
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
|
await chromeSafariBrowser.open(
|
||||||
|
url: Uri.parse("https://github.com/flutter"));
|
||||||
|
await chromeSafariBrowser.browserCreated.future;
|
||||||
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
|
expect(() async {
|
||||||
|
await chromeSafariBrowser.open(url: Uri.parse("https://flutter.dev"));
|
||||||
|
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
||||||
|
|
||||||
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
|
await chromeSafariBrowser.close();
|
||||||
|
await chromeSafariBrowser.browserClosed.future;
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
});
|
||||||
|
|
||||||
test('Custom Tabs single instance', () async {
|
test('Custom Tabs single instance', () async {
|
||||||
var chromeSafariBrowser = new MyChromeSafariBrowser();
|
var chromeSafariBrowser = new MyChromeSafariBrowser();
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
|
||||||
import 'main.dart';
|
import 'main.dart';
|
||||||
|
@ -32,8 +33,20 @@ class _ChromeSafariBrowserExampleScreenState
|
||||||
extends State<ChromeSafariBrowserExampleScreen> {
|
extends State<ChromeSafariBrowserExampleScreen> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
rootBundle.load('assets/images/flutter-logo.png').then((actionButtonIcon) {
|
||||||
|
widget.browser.setActionButton(ChromeSafariBrowserActionButton(
|
||||||
|
id: 1,
|
||||||
|
description: 'Action Button description',
|
||||||
|
icon: actionButtonIcon.buffer.asUint8List(),
|
||||||
|
action: (url, title) {
|
||||||
|
print('Action Button 1 clicked!');
|
||||||
|
print(url);
|
||||||
|
print(title);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
widget.browser.addMenuItem(ChromeSafariBrowserMenuItem(
|
widget.browser.addMenuItem(ChromeSafariBrowserMenuItem(
|
||||||
id: 1,
|
id: 2,
|
||||||
label: 'Custom item menu 1',
|
label: 'Custom item menu 1',
|
||||||
action: (url, title) {
|
action: (url, title) {
|
||||||
print('Custom item menu 1 clicked!');
|
print('Custom item menu 1 clicked!');
|
||||||
|
@ -41,7 +54,7 @@ class _ChromeSafariBrowserExampleScreenState
|
||||||
print(title);
|
print(title);
|
||||||
}));
|
}));
|
||||||
widget.browser.addMenuItem(ChromeSafariBrowserMenuItem(
|
widget.browser.addMenuItem(ChromeSafariBrowserMenuItem(
|
||||||
id: 2,
|
id: 3,
|
||||||
label: 'Custom item menu 2',
|
label: 'Custom item menu 2',
|
||||||
action: (url, title) {
|
action: (url, title) {
|
||||||
print('Custom item menu 2 clicked!');
|
print('Custom item menu 2 clicked!');
|
||||||
|
|
|
@ -169,6 +169,20 @@ class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
|
||||||
this.url = url.toString();
|
this.url = url.toString();
|
||||||
urlController.text = this.url;
|
urlController.text = this.url;
|
||||||
});
|
});
|
||||||
|
if (url?.host == 'github.com') {
|
||||||
|
await controller.loadUrl(
|
||||||
|
urlRequest: URLRequest(
|
||||||
|
url: Uri.parse('https://flutter-header-echo.herokuapp.com/'),
|
||||||
|
headers: {
|
||||||
|
'test_header': 'flutter_test_header'
|
||||||
|
}));
|
||||||
|
final String? currentUrl = (await controller.getUrl())?.toString();
|
||||||
|
print(currentUrl);
|
||||||
|
await Future.delayed(Duration(seconds: 2));
|
||||||
|
final String? content = await controller.evaluateJavascript(
|
||||||
|
source: 'document.documentElement.innerText');
|
||||||
|
print(content);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onLoadError: (controller, url, code, message) {
|
onLoadError: (controller, url, code, message) {
|
||||||
pullToRefreshController.endRefreshing();
|
pullToRefreshController.endRefreshing();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_inappwebview/src/util.dart';
|
import 'package:flutter_inappwebview/src/util.dart';
|
||||||
|
@ -40,6 +41,7 @@ class ChromeSafariBrowser {
|
||||||
///View ID used internally.
|
///View ID used internally.
|
||||||
late final String id;
|
late final String id;
|
||||||
|
|
||||||
|
ChromeSafariBrowserActionButton? _actionButton;
|
||||||
Map<int, ChromeSafariBrowserMenuItem> _menuItems = new HashMap();
|
Map<int, ChromeSafariBrowserMenuItem> _menuItems = new HashMap();
|
||||||
bool _isOpened = false;
|
bool _isOpened = false;
|
||||||
late MethodChannel _channel;
|
late MethodChannel _channel;
|
||||||
|
@ -66,12 +68,14 @@ class ChromeSafariBrowser {
|
||||||
onClosed();
|
onClosed();
|
||||||
this._isOpened = false;
|
this._isOpened = false;
|
||||||
break;
|
break;
|
||||||
case "onChromeSafariBrowserMenuItemActionPerform":
|
case "onChromeSafariBrowserItemActionPerform":
|
||||||
String url = call.arguments["url"];
|
String url = call.arguments["url"];
|
||||||
String title = call.arguments["title"];
|
String title = call.arguments["title"];
|
||||||
int id = call.arguments["id"].toInt();
|
int id = call.arguments["id"].toInt();
|
||||||
if (this._menuItems[id] != null) {
|
if (this._actionButton?.id == id) {
|
||||||
this._menuItems[id]!.action(url, title);
|
this._actionButton?.action(url, title);
|
||||||
|
} else if (this._menuItems[id] != null) {
|
||||||
|
this._menuItems[id]?.action(url, title);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -91,13 +95,14 @@ class ChromeSafariBrowser {
|
||||||
|
|
||||||
List<Map<String, dynamic>> menuItemList = [];
|
List<Map<String, dynamic>> menuItemList = [];
|
||||||
_menuItems.forEach((key, value) {
|
_menuItems.forEach((key, value) {
|
||||||
menuItemList.add({"id": value.id, "label": value.label});
|
menuItemList.add(value.toMap());
|
||||||
});
|
});
|
||||||
|
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('id', () => id);
|
args.putIfAbsent('id', () => id);
|
||||||
args.putIfAbsent('url', () => url.toString());
|
args.putIfAbsent('url', () => url.toString());
|
||||||
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
args.putIfAbsent('options', () => options?.toMap() ?? {});
|
||||||
|
args.putIfAbsent('actionButton', () => _actionButton?.toMap());
|
||||||
args.putIfAbsent('menuItemList', () => menuItemList);
|
args.putIfAbsent('menuItemList', () => menuItemList);
|
||||||
await _sharedChannel.invokeMethod('open', args);
|
await _sharedChannel.invokeMethod('open', args);
|
||||||
this._isOpened = true;
|
this._isOpened = true;
|
||||||
|
@ -109,6 +114,16 @@ class ChromeSafariBrowser {
|
||||||
await _channel.invokeMethod("close", args);
|
await _channel.invokeMethod("close", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Set a custom action button.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android ([Official API - CustomTabsIntent.Builder.setActionButton ](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsIntent.Builder#setActionButton(android.graphics.Bitmap,%20java.lang.String,%20android.app.PendingIntent,%20boolean)))
|
||||||
|
void setActionButton(ChromeSafariBrowserActionButton actionButton) {
|
||||||
|
this._actionButton = actionButton;
|
||||||
|
}
|
||||||
|
|
||||||
///Adds a [ChromeSafariBrowserMenuItem] to the menu.
|
///Adds a [ChromeSafariBrowserMenuItem] to the menu.
|
||||||
///
|
///
|
||||||
///**NOTE**: Not available in an Android Trusted Web Activity.
|
///**NOTE**: Not available in an Android Trusted Web Activity.
|
||||||
|
@ -164,11 +179,54 @@ class ChromeSafariBrowser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Class that represents a custom action button for a [ChromeSafariBrowser] instance.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in an Android Trusted Web Activity.
|
||||||
|
class ChromeSafariBrowserActionButton {
|
||||||
|
///The action button id. It should be different from the [ChromeSafariBrowserMenuItem.id].
|
||||||
|
int id;
|
||||||
|
|
||||||
|
///The icon byte data.
|
||||||
|
Uint8List icon;
|
||||||
|
|
||||||
|
///The description for the button. To be used for accessibility.
|
||||||
|
String description;
|
||||||
|
|
||||||
|
///Whether the action button should be tinted.
|
||||||
|
bool shouldTint;
|
||||||
|
|
||||||
|
///Callback function to be invoked when the menu item is clicked
|
||||||
|
final void Function(String url, String title) action;
|
||||||
|
|
||||||
|
ChromeSafariBrowserActionButton(
|
||||||
|
{required this.id, required this.icon,
|
||||||
|
required this.description, required this.action,
|
||||||
|
this.shouldTint = false});
|
||||||
|
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"id": id,
|
||||||
|
"icon": icon,
|
||||||
|
"description": description,
|
||||||
|
"shouldTint": shouldTint
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return this.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return toMap().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///Class that represents a custom menu item for a [ChromeSafariBrowser] instance.
|
///Class that represents a custom menu item for a [ChromeSafariBrowser] instance.
|
||||||
///
|
///
|
||||||
///**NOTE**: Not available in an Android Trusted Web Activity.
|
///**NOTE**: Not available in an Android Trusted Web Activity.
|
||||||
class ChromeSafariBrowserMenuItem {
|
class ChromeSafariBrowserMenuItem {
|
||||||
///The menu item id
|
///The menu item id. It should be different from [ChromeSafariBrowserActionButton.id].
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
///The label of the menu item
|
///The label of the menu item
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
Loading…
Reference in New Issue