diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e6b90aa..fb1718fc 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Updated Android context menu workaround - Calling `onCreateContextMenu` event on iOS also when the context menu is disabled in order to have the same effect as Android - Added Android keyboard workaround to hide the keyboard when clicking other HTML elements, losing the focus on the previous input +- Added `onEnterFullscreen`, `onExitFullscreen` webview events - Fixed `Print preview is not working? java.lang.IllegalStateException: Can print only from an activity` [#128](https://github.com/pichillilorenzo/flutter_inappwebview/issues/128) ## 3.2.0 diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java index 6cb537c3..9f1b5097 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/FlutterWebView.java @@ -54,6 +54,8 @@ public class FlutterWebView implements PlatformView, MethodCallHandler { InAppWebViewOptions options = new InAppWebViewOptions(); options.parse(initialOptions); + Log.d(LOG_TAG, "\n\n\n Shared.activity " + ((Shared.activity == null) ? "is null" : "is NOT null!") + "\n\n\n"); + webView = new InAppWebView(Shared.activity, this, id, options, contextMenu, containerView); displayListenerProxy.onPostWebViewInitialization(displayManager); diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java index ef697ac4..c9846ce8 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebView/InAppWebViewChromeClient.java @@ -88,6 +88,11 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR Shared.activity.setRequestedOrientation(this.mOriginalOrientation); this.mCustomViewCallback.onCustomViewHidden(); this.mCustomViewCallback = null; + + Map obj = new HashMap<>(); + if (inAppBrowserActivity != null) + obj.put("uuid", inAppBrowserActivity.uuid); + channel.invokeMethod("onExitFullscreen", obj); } @Override @@ -125,6 +130,11 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN); } + + Map obj = new HashMap<>(); + if (inAppBrowserActivity != null) + obj.put("uuid", inAppBrowserActivity.uuid); + channel.invokeMethod("onEnterFullscreen", obj); } @Override @@ -549,8 +559,6 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR super.onReceivedIcon(view, icon); } - //The undocumented magic method override - //Eclipse will swear at you if you try to put @Override here // For Android 3.0+ public void openFileChooser(ValueCallback uploadMsg) { @@ -573,7 +581,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR FILECHOOSER_RESULTCODE); } - //For Android 4.1 + // For Android 4.1 public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) { mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); @@ -583,7 +591,7 @@ public class InAppWebViewChromeClient extends WebChromeClient implements PluginR } - //For Android 5.0+ + // For Android 5.0+ public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { InAppWebViewFlutterPlugin.uploadMessageArray = filePathCallback; try { diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java index cdaeb5ec..e21dec63 100755 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappwebview/InAppWebViewFlutterPlugin.java @@ -4,6 +4,7 @@ import android.app.Activity; import android.content.Context; import android.net.Uri; import android.os.Build; +import android.util.Log; import android.webkit.ValueCallback; import com.pichillilorenzo.flutter_inappwebview.InAppWebView.FlutterWebViewFactory; @@ -47,6 +48,9 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger, Activity activity, PlatformViewRegistry platformViewRegistry, FlutterView flutterView) { + + Log.d(LOG_TAG, "\n\n\n onAttachedToEngine CALLED! \n\n\n"); + Shared.applicationContext = applicationContext; Shared.activity = activity; Shared.messenger = messenger; @@ -67,6 +71,9 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { @Override public void onDetachedFromEngine(FlutterPluginBinding binding) { + + Log.d(LOG_TAG, "\n\n\n onDetachedFromEngine CALLED! \n\n\n"); + if (inAppBrowserManager != null) { inAppBrowserManager.dispose(); inAppBrowserManager = null; @@ -100,24 +107,36 @@ public class InAppWebViewFlutterPlugin implements FlutterPlugin, ActivityAware { @Override public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) { + + Log.d(LOG_TAG, "\n\n\n onAttachedToActivity CALLED! \n\n\n"); + Shared.activityPluginBinding = activityPluginBinding; Shared.activity = activityPluginBinding.getActivity(); } @Override public void onDetachedFromActivityForConfigChanges() { + + Log.d(LOG_TAG, "\n\n\n onDetachedFromActivityForConfigChanges CALLED! \n\n\n"); + Shared.activityPluginBinding = null; Shared.activity = null; } @Override public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) { + + Log.d(LOG_TAG, "\n\n\n onReattachedToActivityForConfigChanges CALLED! \n\n\n"); + Shared.activityPluginBinding = activityPluginBinding; Shared.activity = activityPluginBinding.getActivity(); } @Override public void onDetachedFromActivity() { + + Log.d(LOG_TAG, "\n\n\n onDetachedFromActivity CALLED! \n\n\n"); + Shared.activityPluginBinding = null; Shared.activity = null; } diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies index 0b26639a..8f13f275 100755 --- a/example/.flutter-plugins-dependencies +++ b/example/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity-0.4.8+5/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.7/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-3.3.0/","dependencies":[]}],"android":[{"name":"connectivity","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity-0.4.8+5/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.7/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-3.3.0/","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_macos-0.1.0+3/","dependencies":[]},{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+2/","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"connectivity","dependencies":["connectivity_macos"]},{"name":"connectivity_macos","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-05-22 12:58:00.364435","version":"1.17.1"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity-0.4.8+5/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.7/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-3.3.0/","dependencies":[]}],"android":[{"name":"connectivity","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity-0.4.8+5/","dependencies":[]},{"name":"flutter_downloader","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_downloader-1.4.4/","dependencies":[]},{"name":"flutter_inappwebview","path":"/Users/lorenzopichilli/Desktop/flutter_inappwebview/","dependencies":[]},{"name":"path_provider","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.7/","dependencies":[]},{"name":"permission_handler","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/permission_handler-3.3.0/","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/connectivity_macos-0.1.0+3/","dependencies":[]},{"name":"path_provider_macos","path":"/Users/lorenzopichilli/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+2/","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"connectivity","dependencies":["connectivity_macos"]},{"name":"connectivity_macos","dependencies":[]},{"name":"flutter_downloader","dependencies":[]},{"name":"flutter_inappwebview","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"permission_handler","dependencies":[]}],"date_created":"2020-05-22 16:46:33.343831","version":"1.17.1"} \ No newline at end of file diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh index 4882a9e9..fb55de39 100755 --- a/example/ios/Flutter/flutter_export_environment.sh +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -2,10 +2,11 @@ # This is a generated file; do not edit or check into version control. export "FLUTTER_ROOT=/Users/lorenzopichilli/flutter" export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example" -export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart" export "FLUTTER_BUILD_DIR=build" export "SYMROOT=${SOURCE_ROOT}/../build/ios" export "OTHER_LDFLAGS=$(inherited) -framework Flutter" export "FLUTTER_FRAMEWORK_DIR=/Users/lorenzopichilli/flutter/bin/cache/artifacts/engine/ios" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" +export "TRACK_WIDGET_CREATION=true" diff --git a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100755 index 6b30c745..00000000 --- a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,10 +0,0 @@ - - - - - BuildSystemType - Original - PreviewsEnabled - - - diff --git a/example/lib/in_app_webiew_example.screen.dart b/example/lib/in_app_webiew_example.screen.dart index 88c90292..1d88b611 100755 --- a/example/lib/in_app_webiew_example.screen.dart +++ b/example/lib/in_app_webiew_example.screen.dart @@ -76,7 +76,7 @@ class _InAppWebViewExampleScreenState extends State { BoxDecoration(border: Border.all(color: Colors.blueAccent)), child: InAppWebView( contextMenu: contextMenu, - initialUrl: "https://github.com/flutter", + initialUrl: "https://www.youtube.com/watch?v=oD5RtLhhubg", // initialFile: "assets/index.html", initialHeaders: {}, initialOptions: InAppWebViewGroupOptions( diff --git a/ios/Classes/InAppWebView.swift b/ios/Classes/InAppWebView.swift index 54f8933d..682fe49f 100755 --- a/ios/Classes/InAppWebView.swift +++ b/ios/Classes/InAppWebView.swift @@ -860,6 +860,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi lastTouchPointTimestamp = Int64(Date().timeIntervalSince1970 * 1000) SharedLastTouchPointTimestamp[self] = lastTouchPointTimestamp + // re-build context menu items for the current webview UIMenuController.shared.menuItems = [] if let menu = self.contextMenu { if let menuItems = menu["menuItems"] as? [[String : Any]] { @@ -903,6 +904,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi } return false } + if contextMenuIsShowing, !action.description.starts(with: "onContextMenuActionItemClicked-") { let id = action.description.compactMap({ $0.asciiValue?.description }).joined() let arguments: [String: Any?] = [ @@ -944,6 +946,18 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi name: UIMenuController.didHideMenuNotification, object: nil) + // listen for videos playing in fullscreen + NotificationCenter.default.addObserver(self, + selector: #selector(onEnterFullscreen(_:)), + name: UIWindow.didBecomeVisibleNotification, + object: window) + + // listen for videos stopping to play in fullscreen + NotificationCenter.default.addObserver(self, + selector: #selector(onExitFullscreen(_:)), + name: UIWindow.didBecomeHiddenNotification, + object: window) + configuration.userContentController = WKUserContentController() configuration.preferences = WKPreferences() @@ -2480,6 +2494,34 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate, WKNavi channel?.invokeMethod("onDidReceiveServerRedirectForProvisionalNavigation", arguments: []) } + // https://stackoverflow.com/a/42840541/4637638 + public func isVideoPlayerWindow(_ notificationObject: AnyObject?) -> Bool { + let nonVideoClasses = ["_UIAlertControllerShimPresenterWindow", + "UITextEffectsWindow", + "UIRemoteKeyboardWindow"] + var isVideo = true + if let obj = notificationObject { + for nonVideoClass in nonVideoClasses { + if let clazz = NSClassFromString(nonVideoClass) { + isVideo = isVideo && !(obj.isKind(of: clazz)) + } + } + } + return isVideo + } + + @objc func onEnterFullscreen(_ notification: Notification) { + if (isVideoPlayerWindow(notification.object as AnyObject?)) { + channel?.invokeMethod("onEnterFullscreen", arguments: []) + } + } + + @objc func onExitFullscreen(_ notification: Notification) { + if (isVideoPlayerWindow(notification.object as AnyObject?)) { + channel?.invokeMethod("onExitFullscreen", arguments: []) + } + } + // public func onContextMenuConfigurationForElement(linkURL: String?, result: FlutterResult?) { // let arguments: [String: Any?] = ["linkURL": linkURL] // channel?.invokeMethod("onContextMenuConfigurationForElement", arguments: arguments, result: result)