merge
This commit is contained in:
commit
df6fe3f8ce
|
@ -7,6 +7,10 @@
|
|||
- Added support for `onPermissionRequest` event on iOS 15.0+
|
||||
- Updated `getMetaThemeColor` on iOS 15.0+
|
||||
|
||||
## 5.4.2+1
|
||||
|
||||
- Fixed "Latest version 5.4.2 crashes on Android - HeadlessInAppWebView.dispose" [#1155](https://github.com/pichillilorenzo/flutter_inappwebview/issues/1155)
|
||||
|
||||
## 5.4.2
|
||||
|
||||
- Added `setActionButton` method to `ChromeSafariBrowser` class
|
||||
|
|
|
@ -6,6 +6,8 @@ import android.net.Uri;
|
|||
import android.os.Build;
|
||||
import android.webkit.ValueCallback;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.pichillilorenzo.flutter_inappwebview.chrome_custom_tabs.ChromeSafariBrowserManager;
|
||||
import com.pichillilorenzo.flutter_inappwebview.credential_database.CredentialDatabaseHandler;
|
||||
import com.pichillilorenzo.flutter_inappwebview.in_app_browser.InAppBrowserManager;
|
||||
|
@ -41,7 +43,9 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware {
|
|||
public PluginRegistry.Registrar registrar;
|
||||
public BinaryMessenger messenger;
|
||||
public FlutterPlugin.FlutterAssets flutterAssets;
|
||||
@Nullable
|
||||
public ActivityPluginBinding activityPluginBinding;
|
||||
@Nullable
|
||||
public Activity activity;
|
||||
@SuppressWarnings("deprecation")
|
||||
public FlutterView flutterView;
|
||||
|
|
|
@ -79,7 +79,7 @@ public class InAppWebViewStatic implements MethodChannel.MethodCallHandler {
|
|||
result.success(false);
|
||||
break;
|
||||
case "getCurrentWebViewPackage":
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && plugin != null && plugin.activity != null) {
|
||||
result.success(convertWebViewPackageToMap(WebViewCompat.getCurrentWebViewPackage(plugin.activity)));
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
//with Android Lollipop (API 21) they started to update the WebView
|
||||
|
|
|
@ -41,6 +41,7 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
|||
protected final int CHROME_CUSTOM_TAB_REQUEST_CODE = 100;
|
||||
protected boolean onChromeSafariBrowserOpened = false;
|
||||
protected boolean onChromeSafariBrowserCompletedInitialLoad = false;
|
||||
@Nullable
|
||||
public ChromeSafariBrowserManager manager;
|
||||
public String initialUrl;
|
||||
public List<CustomTabsMenuItem> menuItems = new ArrayList<>();
|
||||
|
@ -137,11 +138,13 @@ public class ChromeCustomTabsActivity extends Activity implements MethodChannel.
|
|||
this.onDestroy();
|
||||
this.close();
|
||||
|
||||
// https://stackoverflow.com/a/41596629/4637638
|
||||
Intent myIntent = new Intent(manager.plugin.activity, manager.plugin.activity.getClass());
|
||||
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
myIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
manager.plugin.activity.startActivity(myIntent);
|
||||
if (manager != null && manager.plugin != null && manager.plugin.activity != null) {
|
||||
// https://stackoverflow.com/a/41596629/4637638
|
||||
Intent myIntent = new Intent(manager.plugin.activity, manager.plugin.activity.getClass());
|
||||
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
myIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
manager.plugin.activity.startActivity(myIntent);
|
||||
}
|
||||
|
||||
dispose();
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
|||
|
||||
switch (call.method) {
|
||||
case "open":
|
||||
if (plugin != null) {
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
String url = (String) call.argument("url");
|
||||
HashMap<String, Object> settings = (HashMap<String, Object>) call.argument("settings");
|
||||
HashMap<String, Object> actionButton = (HashMap<String, Object>) call.argument("actionButton");
|
||||
|
@ -52,7 +52,7 @@ public class ChromeSafariBrowserManager implements MethodChannel.MethodCallHandl
|
|||
}
|
||||
break;
|
||||
case "isAvailable":
|
||||
if (plugin != null) {
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
result.success(CustomTabActivityHelper.isAvailable(plugin.activity));
|
||||
} else {
|
||||
result.success(false);
|
||||
|
|
|
@ -70,21 +70,23 @@ public class HeadlessInAppWebView implements MethodChannel.MethodCallHandler {
|
|||
}
|
||||
|
||||
public void prepare(Map<String, Object> params) {
|
||||
// Add the headless WebView to the view hierarchy.
|
||||
// This way is also possible to take screenshots.
|
||||
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
|
||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||
if (mainView != null) {
|
||||
View view = flutterWebView.getView();
|
||||
final Map<String, Object> initialSize = (Map<String, Object>) params.get("initialSize");
|
||||
Size2D size = Size2D.fromMap(initialSize);
|
||||
if (size != null) {
|
||||
setSize(size);
|
||||
} else {
|
||||
view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
// Add the headless WebView to the view hierarchy.
|
||||
// This way is also possible to take screenshots.
|
||||
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
|
||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||
if (mainView != null && flutterWebView != null) {
|
||||
View view = flutterWebView.getView();
|
||||
final Map<String, Object> initialSize = (Map<String, Object>) params.get("initialSize");
|
||||
Size2D size = Size2D.fromMap(initialSize);
|
||||
if (size != null) {
|
||||
setSize(size);
|
||||
} else {
|
||||
view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
}
|
||||
mainView.addView(view, 0);
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
mainView.addView(view, 0);
|
||||
view.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +112,7 @@ public class HeadlessInAppWebView implements MethodChannel.MethodCallHandler {
|
|||
public void dispose() {
|
||||
channel.setMethodCallHandler(null);
|
||||
HeadlessInAppWebViewManager.webViews.remove(id);
|
||||
if (plugin != null) {
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
ViewGroup contentView = (ViewGroup) plugin.activity.findViewById(android.R.id.content);
|
||||
ViewGroup mainView = (ViewGroup) (contentView).getChildAt(0);
|
||||
if (mainView != null && flutterWebView != null) {
|
||||
|
|
|
@ -72,13 +72,19 @@ public class InAppBrowserManager implements MethodChannel.MethodCallHandler {
|
|||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
switch (call.method) {
|
||||
case "open":
|
||||
open(plugin.activity, (Map<String, Object>) call.arguments());
|
||||
result.success(true);
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
open(plugin.activity, (Map<String, Object>) call.arguments());
|
||||
result.success(true);
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
case "openWithSystemBrowser":
|
||||
{
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
String url = (String) call.argument("url");
|
||||
openWithSystemBrowser(plugin.activity, url, result);
|
||||
} else {
|
||||
result.success(false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -60,7 +60,7 @@ public class FlutterWebView implements PlatformWebView {
|
|||
InAppWebViewSettings options = new InAppWebViewSettings();
|
||||
options.parse(initialSettings);
|
||||
|
||||
if (plugin.activity == null) {
|
||||
if (plugin == null || plugin.activity == null) {
|
||||
Log.e(LOG_TAG, "\n\n\nERROR: You need to upgrade your Flutter project to use the new Java Embedding API:\n\n" +
|
||||
"- Take a look at the \"IMPORTANT Note for Android\" section here: https://github.com/pichillilorenzo/flutter_inappwebview#important-note-for-android\n" +
|
||||
"- See the official wiki here: https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects\n\n\n");
|
||||
|
|
|
@ -175,7 +175,9 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
|||
this.customSettings = customSettings;
|
||||
this.contextMenu = contextMenu;
|
||||
this.userContentController.addUserOnlyScripts(userScripts);
|
||||
plugin.activity.registerForContextMenu(this);
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
plugin.activity.registerForContextMenu(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void prepare() {
|
||||
|
@ -1216,20 +1218,22 @@ final public class InAppWebView extends InputAwareWebView implements InAppWebVie
|
|||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
public void printCurrentPage() {
|
||||
// Get a PrintManager instance
|
||||
PrintManager printManager = (PrintManager) plugin.activity.getSystemService(Context.PRINT_SERVICE);
|
||||
if (plugin != null && plugin.activity != null) {
|
||||
// Get a PrintManager instance
|
||||
PrintManager printManager = (PrintManager) plugin.activity.getSystemService(Context.PRINT_SERVICE);
|
||||
|
||||
if (printManager != null) {
|
||||
String jobName = getTitle() + " Document";
|
||||
if (printManager != null) {
|
||||
String jobName = getTitle() + " Document";
|
||||
|
||||
// Get a printCurrentPage adapter instance
|
||||
PrintDocumentAdapter printAdapter = createPrintDocumentAdapter(jobName);
|
||||
// Get a printCurrentPage adapter instance
|
||||
PrintDocumentAdapter printAdapter = createPrintDocumentAdapter(jobName);
|
||||
|
||||
// Create a printCurrentPage job with name and adapter instance
|
||||
printManager.print(jobName, printAdapter,
|
||||
new PrintAttributes.Builder().build());
|
||||
} else {
|
||||
Log.e(LOG_TAG, "No PrintManager available");
|
||||
// Create a printCurrentPage job with name and adapter instance
|
||||
printManager.print(jobName, printAdapter,
|
||||
new PrintAttributes.Builder().build());
|
||||
} else {
|
||||
Log.e(LOG_TAG, "No PrintManager available");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
|
||||
if (plugin.registrar != null)
|
||||
plugin.registrar.addActivityResultListener(this);
|
||||
else
|
||||
else if (plugin.activityPluginBinding != null)
|
||||
plugin.activityPluginBinding.addActivityResultListener(this);
|
||||
}
|
||||
|
||||
|
@ -124,9 +124,15 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
|
||||
@Override
|
||||
public void onHideCustomView() {
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
View decorView = getRootView();
|
||||
if (decorView == null) {
|
||||
return;
|
||||
}
|
||||
((FrameLayout) decorView).removeView(this.mCustomView);
|
||||
this.mCustomView = null;
|
||||
decorView.setSystemUiVisibility(this.mOriginalSystemUiVisibility);
|
||||
|
@ -145,9 +151,15 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
return;
|
||||
}
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
View decorView = getRootView();
|
||||
if (decorView == null) {
|
||||
return;
|
||||
}
|
||||
this.mCustomView = paramView;
|
||||
this.mOriginalSystemUiVisibility = decorView.getSystemUiVisibility();
|
||||
this.mOriginalOrientation = activity.getRequestedOrientation();
|
||||
|
@ -229,7 +241,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
};
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
|
||||
alertDialogBuilder.setMessage(alertMessage);
|
||||
|
@ -322,7 +337,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
};
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
|
||||
alertDialogBuilder.setMessage(alertMessage);
|
||||
|
@ -441,7 +459,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
};
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
|
||||
alertDialogBuilder.setMessage(alertMessage);
|
||||
|
@ -539,7 +560,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
};
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity, R.style.Theme_AppCompat_Dialog_Alert);
|
||||
alertDialogBuilder.setMessage(alertMessage);
|
||||
|
@ -746,8 +770,12 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
channel.invokeMethod("onReceivedTouchIconUrl", obj);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ViewGroup getRootView() {
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return null;
|
||||
}
|
||||
return (ViewGroup) activity.findViewById(android.R.id.content);
|
||||
}
|
||||
|
||||
|
@ -841,7 +869,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
|
||||
private boolean isFileNotEmpty(Uri uri) {
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long length;
|
||||
try {
|
||||
|
@ -882,7 +913,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{}));
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
if (chooserIntent.resolveActivity(activity.getPackageManager()) != null) {
|
||||
activity.startActivityForResult(chooserIntent, PICKER_LEGACY);
|
||||
} else {
|
||||
|
@ -910,7 +944,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
chooserIntent.putExtra(Intent.EXTRA_INTENT, fileSelectionIntent);
|
||||
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents.toArray(new Parcelable[]{}));
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return true;
|
||||
}
|
||||
if (chooserIntent.resolveActivity(activity.getPackageManager()) != null) {
|
||||
activity.startActivityForResult(chooserIntent, PICKER);
|
||||
} else {
|
||||
|
@ -923,7 +960,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
protected boolean needsCameraPermission() {
|
||||
boolean needed = false;
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return true;
|
||||
}
|
||||
PackageManager packageManager = activity.getPackageManager();
|
||||
try {
|
||||
String[] requestedPermissions = packageManager.getPackageInfo(activity.getApplicationContext().getPackageName(), PackageManager.GET_PERMISSIONS).requestedPermissions;
|
||||
|
@ -1051,6 +1091,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
return type;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Uri getOutputUri(String intentType) {
|
||||
File capturedFile = null;
|
||||
try {
|
||||
|
@ -1065,12 +1106,16 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
return Uri.fromFile(capturedFile);
|
||||
}
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return null;
|
||||
}
|
||||
// for versions 6.0+ (23) we use the FileProvider to avoid runtime permissions
|
||||
String packageName = activity.getApplicationContext().getPackageName();
|
||||
return FileProvider.getUriForFile(activity.getApplicationContext(), packageName + "." + fileProviderAuthorityExtension, capturedFile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private File getCapturedFile(String intentType) throws IOException {
|
||||
String prefix = "";
|
||||
String suffix = "";
|
||||
|
@ -1095,7 +1140,10 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
return new File(storageDir, filename);
|
||||
}
|
||||
|
||||
Activity activity = inAppBrowserDelegate != null ? inAppBrowserDelegate.getActivity() : plugin.activity;
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return null;
|
||||
}
|
||||
File storageDir = activity.getApplicationContext().getExternalFilesDir(null);
|
||||
return File.createTempFile(prefix, suffix, storageDir);
|
||||
}
|
||||
|
@ -1154,6 +1202,16 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Activity getActivity() {
|
||||
if (inAppBrowserDelegate != null) {
|
||||
return inAppBrowserDelegate.getActivity();
|
||||
} else if (plugin != null) {
|
||||
return plugin.activity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (plugin != null && plugin.activityPluginBinding != null) {
|
||||
plugin.activityPluginBinding.removeActivityResultListener(this);
|
||||
|
|
|
@ -15,6 +15,21 @@ import 'package:path_provider/path_provider.dart';
|
|||
|
||||
import '.env.dart';
|
||||
|
||||
/// Returns a matcher that matches the isNullOrEmpty property.
|
||||
const Matcher isNullOrEmpty = _NullOrEmpty();
|
||||
|
||||
class _NullOrEmpty extends Matcher {
|
||||
const _NullOrEmpty();
|
||||
|
||||
@override
|
||||
bool matches(Object? item, Map matchState) =>
|
||||
item == null || (item as dynamic).isEmpty;
|
||||
|
||||
@override
|
||||
Description describe(Description description) =>
|
||||
description.add('null or empty');
|
||||
}
|
||||
|
||||
class Foo {
|
||||
String? bar;
|
||||
String? baz;
|
||||
|
@ -4148,7 +4163,7 @@ setTimeout(function() {
|
|||
if (Platform.isAndroid) {
|
||||
await pageLoaded.future;
|
||||
expect(await controller.evaluateJavascript(source: "document.body"),
|
||||
isEmpty);
|
||||
isNullOrEmpty);
|
||||
} else if (Platform.isIOS) {
|
||||
expect(pageLoaded.future, doesNotComplete);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue