diff --git a/.idea/workspace.xml b/.idea/workspace.xml index a2b99c7e..76a4cce8 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,23 +1,39 @@ + + + + + - - - - + + + + + + - + - - - - - + + + + + + + + + + + + + + - - + + @@ -36,21 +52,11 @@ - - - - - - - - - - - - + + @@ -61,8 +67,8 @@ - - + + @@ -155,9 +161,9 @@ - @@ -176,10 +182,7 @@ - - - @@ -187,30 +190,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -232,6 +211,9 @@ + + + @@ -418,27 +400,26 @@ - + - - + - + - + @@ -451,6 +432,7 @@ + @@ -810,19 +792,10 @@ - - - - - - - - - @@ -830,14 +803,21 @@ + + + + + + + - - + + @@ -846,8 +826,8 @@ - - + + diff --git a/android/build.gradle b/android/build.gradle index 24f18e77..020a51c9 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -25,8 +25,10 @@ android { compileSdkVersion 27 defaultConfig { - minSdkVersion 16 + minSdkVersion 17 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + + vectorDrawables.useSupportLibrary = true } lintOptions { disable 'InvalidPackage' @@ -35,4 +37,6 @@ android { dependencies { implementation 'com.android.support:customtabs:27.1.1' -} \ No newline at end of file + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' +} diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index c3e20824..b3fb1d28 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,6 +1,12 @@ + + package="com.pichillilorenzo.flutter_inappbrowser"> - + - + + + + + \ No newline at end of file diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java index d38cbc0e..7819ad2c 100644 --- a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java @@ -26,6 +26,7 @@ import android.app.Activity; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; +import android.os.Parcelable; import android.provider.Browser; import android.content.res.Resources; import android.graphics.Bitmap; @@ -34,10 +35,12 @@ import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.support.annotation.RequiresApi; import android.text.InputType; import android.util.TypedValue; import android.view.Gravity; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; @@ -58,10 +61,12 @@ import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.util.Log; +import android.support.v7.app.AppCompatActivity; import org.json.JSONException; import org.json.JSONObject; +import java.io.Serializable; import java.util.Arrays; import java.util.List; import java.util.HashMap; @@ -78,9 +83,10 @@ import io.flutter.plugin.common.PluginRegistry.Registrar; /** InAppBrowser */ public class InAppBrowser implements MethodCallHandler { - private Registrar registrar; - private Activity activity; - private final MethodChannel channel; + public static Registrar registrar; + public Activity activity; + public static MethodChannel channel; + public static WebViewActivity webViewActivity; private static final String NULL = "null"; protected static final String LOG_TAG = "InAppBrowser"; @@ -146,6 +152,7 @@ public class InAppBrowser implements MethodCallHandler { channel.setMethodCallHandler(new InAppBrowser(registrar, registrar.activity())); } + @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override public void onMethodCall(MethodCall call, final Result result) { String source; @@ -161,7 +168,8 @@ public class InAppBrowser implements MethodCallHandler { t = SELF; } final String target = t; - final HashMap features = parseFeature(call.argument("options").toString()); + final InAppBrowserOptions options = new InAppBrowserOptions(); + options.parse((HashMap) call.argument("options")); Log.d(LOG_TAG, "target = " + target); @@ -188,7 +196,7 @@ public class InAppBrowser implements MethodCallHandler { // load in InAppBrowser else { Log.d(LOG_TAG, "loading in InAppBrowser"); - r = showWebPage(url, features); + r = showWebPage(url, options); } } // SYSTEM @@ -199,7 +207,7 @@ public class InAppBrowser implements MethodCallHandler { // BLANK - or anything else else { Log.d(LOG_TAG, "in blank"); - r = showWebPage(url, features); + r = showWebPage(url, options); } result.success(r); @@ -342,436 +350,456 @@ public class InAppBrowser implements MethodCallHandler { } @TargetApi(8) - private String showWebPage(final String url, HashMap features) { + private String showWebPage(final String url, InAppBrowserOptions options) { + Intent intent = new Intent(activity, WebViewActivity.class); - // Determine if we should hide the location bar. - showLocationBar = true; - showZoomControls = true; - openWindowHidden = false; - mediaPlaybackRequiresUserGesture = false; + Bundle extras = new Bundle(); + extras.putString("url", url); + extras.putSerializable("options", options.getHashMap()); - if (features != null) { - String show = features.get(LOCATION); - if (show != null) { - showLocationBar = show.equals("yes") ? true : false; - } - if(showLocationBar) { - String hideNavigation = features.get(HIDE_NAVIGATION); - String hideUrl = features.get(HIDE_URL); - if(hideNavigation != null) hideNavigationButtons = hideNavigation.equals("yes") ? true : false; - if(hideUrl != null) hideUrlBar = hideUrl.equals("yes") ? true : false; - } - String zoom = features.get(ZOOM); - if (zoom != null) { - showZoomControls = zoom.equals("yes") ? true : false; - } - String hidden = features.get(HIDDEN); - if (hidden != null) { - openWindowHidden = hidden.equals("yes") ? true : false; - } - String hardwareBack = features.get(HARDWARE_BACK_BUTTON); - if (hardwareBack != null) { - hadwareBackButton = hardwareBack.equals("yes") ? true : false; - } else { - hadwareBackButton = DEFAULT_HARDWARE_BACK; - } - String mediaPlayback = features.get(MEDIA_PLAYBACK_REQUIRES_USER_ACTION); - if (mediaPlayback != null) { - mediaPlaybackRequiresUserGesture = mediaPlayback.equals("yes") ? true : false; - } - String cache = features.get(CLEAR_ALL_CACHE); - if (cache != null) { - clearAllCache = cache.equals("yes") ? true : false; - } else { - cache = features.get(CLEAR_SESSION_CACHE); - if (cache != null) { - clearSessionCache = cache.equals("yes") ? true : false; - } - } - String shouldPause = features.get(SHOULD_PAUSE); - if (shouldPause != null) { - shouldPauseInAppBrowser = shouldPause.equals("yes") ? true : false; - } - String wideViewPort = features.get(USER_WIDE_VIEW_PORT); - if (wideViewPort != null ) { - useWideViewPort = wideViewPort.equals("yes") ? true : false; - } - String closeButtonCaptionSet = features.get(CLOSE_BUTTON_CAPTION); - if (closeButtonCaptionSet != null) { - closeButtonCaption = closeButtonCaptionSet; - } - String closeButtonColorSet = features.get(CLOSE_BUTTON_COLOR); - if (closeButtonColorSet != null) { - closeButtonColor = closeButtonColorSet; - } - String toolbarColorSet = features.get(TOOLBAR_COLOR); - if (toolbarColorSet != null) { - toolbarColor = android.graphics.Color.parseColor(toolbarColorSet); - } - String navigationButtonColorSet = features.get(NAVIGATION_COLOR); - if (navigationButtonColorSet != null) { - navigationButtonColor = navigationButtonColorSet; - } - String showFooterSet = features.get(FOOTER); - if (showFooterSet != null) { - showFooter = showFooterSet.equals("yes") ? true : false; - } - String footerColorSet = features.get(FOOTER_COLOR); - if (footerColorSet != null) { - footerColor = footerColorSet; - } - } + intent.putExtras(extras); - // Create dialog in new thread - Runnable runnable = new Runnable() { - /** - * Convert our DIP units to Pixels - * - * @return int - */ - private int dpToPixels(int dipValue) { - int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, - (float) dipValue, - activity.getResources().getDisplayMetrics() - ); + activity.startActivity(intent); - return value; - } + //webViewActivity.loadUrl(url); - @TargetApi(8) - private View createCloseButton(int id){ - View _close; - Resources activityRes = activity.getResources(); - - if (closeButtonCaption != "") { - // Use TextView for text - TextView close = new TextView(activity); - close.setText(closeButtonCaption); - close.setTextSize(20); - if (closeButtonColor != "") close.setTextColor(android.graphics.Color.parseColor(closeButtonColor)); - close.setGravity(android.view.Gravity.CENTER_VERTICAL); - close.setPadding(this.dpToPixels(10), 0, this.dpToPixels(10), 0); - _close = close; - } - else { - ImageButton close = new ImageButton(activity); - int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", activity.getPackageName()); - Drawable closeIcon = activityRes.getDrawable(closeResId); - if (closeButtonColor != "") close.setColorFilter(android.graphics.Color.parseColor(closeButtonColor)); - close.setImageDrawable(closeIcon); - close.setScaleType(ImageView.ScaleType.FIT_CENTER); - if (Build.VERSION.SDK_INT >= 16) - close.getAdjustViewBounds(); - - _close = close; - } - - RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); - _close.setLayoutParams(closeLayoutParams); - - if (Build.VERSION.SDK_INT >= 16) - _close.setBackground(null); - else - _close.setBackgroundDrawable(null); - - _close.setContentDescription("Close Button"); - _close.setId(Integer.valueOf(id)); - _close.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - closeDialog(); - } - }); - - return _close; - } - - @SuppressLint("NewApi") - public void run() { - // CB-6702 InAppBrowser hangs when opening more than one instance - if (dialog != null) { - dialog.dismiss(); - }; - - // Let's create the main dialog - dialog = new InAppBrowserDialog(activity, android.R.style.Theme_NoTitleBar); - dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog; - dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - dialog.setCancelable(true); - dialog.setInAppBroswer(getInAppBrowser()); - - // Main container layout - LinearLayout main = new LinearLayout(activity); - main.setOrientation(LinearLayout.VERTICAL); - - // Toolbar layout - RelativeLayout toolbar = new RelativeLayout(activity); - //Please, no more black! - - toolbar.setBackgroundColor(toolbarColor); - toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44))); - toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2)); - toolbar.setHorizontalGravity(Gravity.LEFT); - toolbar.setVerticalGravity(Gravity.TOP); - - // Action Button Container layout - RelativeLayout actionButtonContainer = new RelativeLayout(activity); - actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); - actionButtonContainer.setHorizontalGravity(Gravity.LEFT); - actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL); - actionButtonContainer.setId(Integer.valueOf(1)); - - // Back button - ImageButton back = new ImageButton(activity); - RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT); - back.setLayoutParams(backLayoutParams); - back.setContentDescription("Back Button"); - back.setId(Integer.valueOf(2)); - Resources activityRes = activity.getResources(); - int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", activity.getPackageName()); - Drawable backIcon = activityRes.getDrawable(backResId); - if (navigationButtonColor != "") back.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor)); - if (Build.VERSION.SDK_INT >= 16) - back.setBackground(null); - else - back.setBackgroundDrawable(null); - back.setImageDrawable(backIcon); - back.setScaleType(ImageView.ScaleType.FIT_CENTER); - back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10)); - if (Build.VERSION.SDK_INT >= 16) - back.getAdjustViewBounds(); - - back.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - goBack(); - } - }); - - // Forward button - ImageButton forward = new ImageButton(activity); - RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); - forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2); - forward.setLayoutParams(forwardLayoutParams); - forward.setContentDescription("Forward Button"); - forward.setId(Integer.valueOf(3)); - int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", activity.getPackageName()); - Drawable fwdIcon = activityRes.getDrawable(fwdResId); - if (navigationButtonColor != "") forward.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor)); - if (Build.VERSION.SDK_INT >= 16) - forward.setBackground(null); - else - forward.setBackgroundDrawable(null); - forward.setImageDrawable(fwdIcon); - forward.setScaleType(ImageView.ScaleType.FIT_CENTER); - forward.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10)); - if (Build.VERSION.SDK_INT >= 16) - forward.getAdjustViewBounds(); - - forward.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - goForward(); - } - }); - - // Edit Text Box - edittext = new EditText(activity); - RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); - textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1); - textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5); - edittext.setLayoutParams(textLayoutParams); - edittext.setId(Integer.valueOf(4)); - edittext.setSingleLine(true); - edittext.setText(url); - edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI); - edittext.setImeOptions(EditorInfo.IME_ACTION_GO); - edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE - edittext.setOnKeyListener(new View.OnKeyListener() { - public boolean onKey(View v, int keyCode, KeyEvent event) { - // If the event is a key-down event on the "enter" button - if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { - navigate(edittext.getText().toString()); - return true; - } - return false; - } - }); - - - // Header Close/Done button - View close = createCloseButton(5); - toolbar.addView(close); - - // Footer - RelativeLayout footer = new RelativeLayout(activity); - int _footerColor; - if(footerColor != ""){ - _footerColor = Color.parseColor(footerColor); - }else{ - _footerColor = android.graphics.Color.LTGRAY; - } - footer.setBackgroundColor(_footerColor); - RelativeLayout.LayoutParams footerLayout = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44)); - footerLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); - footer.setLayoutParams(footerLayout); - if (closeButtonCaption != "") footer.setPadding(this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8)); - footer.setHorizontalGravity(Gravity.LEFT); - footer.setVerticalGravity(Gravity.BOTTOM); - - View footerClose = createCloseButton(7); - footer.addView(footerClose); - - - // WebView - inAppWebView = new WebView(activity); - inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - inAppWebView.setId(Integer.valueOf(6)); - inAppWebView.setWebChromeClient(new WebChromeClient() { - - @Override - public void onProgressChanged(WebView view, int newProgress) { - super.onProgressChanged(view, newProgress); - } - - @Override - public void onReceivedTitle(WebView view, String title) { - super.onReceivedTitle(view, title); - } - - @Override - public void onReceivedIcon(WebView view, Bitmap icon) { - super.onReceivedIcon(view, icon); - } - - // For Android 5.0+ - public boolean onShowFileChooser (WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) - { - Log.d(LOG_TAG, "File Chooser 5.0+"); - // If callback exists, finish it. - if(mUploadCallbackLollipop != null) { - mUploadCallbackLollipop.onReceiveValue(null); - } - mUploadCallbackLollipop = filePathCallback; - - // Create File Chooser Intent - Intent content = new Intent(Intent.ACTION_GET_CONTENT); - content.addCategory(Intent.CATEGORY_OPENABLE); - content.setType("*/*"); - - registrar.context().startActivity(Intent.createChooser(content, "Select File")); - return true; - } - - // For Android 4.1+ - public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) - { - Log.d(LOG_TAG, "File Chooser 4.1+"); - // Call file chooser for Android 3.0+ - openFileChooser(uploadMsg, acceptType); - } - - // For Android 3.0+ - public void openFileChooser(ValueCallback uploadMsg, String acceptType) - { - Log.d(LOG_TAG, "File Chooser 3.0+"); - mUploadCallback = uploadMsg; - Intent content = new Intent(Intent.ACTION_GET_CONTENT); - content.addCategory(Intent.CATEGORY_OPENABLE); - - registrar.context().startActivity(Intent.createChooser(content, "Select File")); - } - }); - WebViewClient client = new InAppBrowserClient(edittext, activity, channel); - inAppWebView.setWebViewClient(client); - WebSettings settings = inAppWebView.getSettings(); - settings.setJavaScriptEnabled(true); - settings.setJavaScriptCanOpenWindowsAutomatically(true); - settings.setBuiltInZoomControls(showZoomControls); - settings.setPluginState(android.webkit.WebSettings.PluginState.ON); - - if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { - settings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture); - } - - String overrideUserAgent = activity.getPreferences(0).getString("OverrideUserAgent", null); - String appendUserAgent = activity.getPreferences(0).getString("AppendUserAgent", null); - - if (overrideUserAgent != null) { - settings.setUserAgentString(overrideUserAgent); - } - if (appendUserAgent != null) { - settings.setUserAgentString(settings.getUserAgentString() + appendUserAgent); - } - - //Toggle whether this is enabled or not! - Bundle appSettings = activity.getIntent().getExtras(); - boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true); - if (enableDatabase) { - String databasePath = activity.getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath(); - settings.setDatabasePath(databasePath); - settings.setDatabaseEnabled(true); - } - settings.setDomStorageEnabled(true); - - if (clearAllCache) { - CookieManager.getInstance().removeAllCookie(); - } else if (clearSessionCache) { - CookieManager.getInstance().removeSessionCookie(); - } - - // Enable Thirdparty Cookies on >=Android 5.0 device - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { - CookieManager.getInstance().setAcceptThirdPartyCookies(inAppWebView,true); - } - - inAppWebView.loadUrl(url); - inAppWebView.setId(Integer.valueOf(6)); - inAppWebView.getSettings().setLoadWithOverviewMode(true); - inAppWebView.getSettings().setUseWideViewPort(useWideViewPort); - inAppWebView.requestFocus(); - inAppWebView.requestFocusFromTouch(); - - // Add the back and forward buttons to our action button container layout - actionButtonContainer.addView(back); - actionButtonContainer.addView(forward); - - // Add the views to our toolbar if they haven't been disabled - if (!hideNavigationButtons) toolbar.addView(actionButtonContainer); - if (!hideUrlBar) toolbar.addView(edittext); - - // Don't add the toolbar if its been disabled - if (getShowLocationBar()) { - // Add our toolbar to our main view/layout - main.addView(toolbar); - } - - // Add our webview to our main view/layout - RelativeLayout webViewLayout = new RelativeLayout(activity); - webViewLayout.addView(inAppWebView); - main.addView(webViewLayout); - - // Don't add the footer unless it's been enabled - if (showFooter) { - webViewLayout.addView(footer); - } - - WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); - lp.copyFrom(dialog.getWindow().getAttributes()); - lp.width = WindowManager.LayoutParams.MATCH_PARENT; - lp.height = WindowManager.LayoutParams.MATCH_PARENT; - - dialog.setContentView(main); - dialog.show(); - dialog.getWindow().setAttributes(lp); - // the goal of openhidden is to load the url and not display it - // Show() needs to be called to cause the URL to be loaded - if(openWindowHidden) { - dialog.hide(); - } - } - }; - this.activity.runOnUiThread(runnable); return ""; + + // Determine if we should hide the location bar. +// showLocationBar = true; +// showZoomControls = true; +// openWindowHidden = false; +// mediaPlaybackRequiresUserGesture = false; + +// if (features != null) { +// String show = features.get(LOCATION); +// if (show != null) { +// showLocationBar = show.equals("yes") ? true : false; +// } +// if(showLocationBar) { +// String hideNavigation = features.get(HIDE_NAVIGATION); +// String hideUrl = features.get(HIDE_URL); +// if(hideNavigation != null) hideNavigationButtons = hideNavigation.equals("yes") ? true : false; +// if(hideUrl != null) hideUrlBar = hideUrl.equals("yes") ? true : false; +// } +// String zoom = features.get(ZOOM); +// if (zoom != null) { +// showZoomControls = zoom.equals("yes") ? true : false; +// } +// String hidden = features.get(HIDDEN); +// if (hidden != null) { +// openWindowHidden = hidden.equals("yes") ? true : false; +// } +// String hardwareBack = features.get(HARDWARE_BACK_BUTTON); +// if (hardwareBack != null) { +// hadwareBackButton = hardwareBack.equals("yes") ? true : false; +// } else { +// hadwareBackButton = DEFAULT_HARDWARE_BACK; +// } +// String mediaPlayback = features.get(MEDIA_PLAYBACK_REQUIRES_USER_ACTION); +// if (mediaPlayback != null) { +// mediaPlaybackRequiresUserGesture = mediaPlayback.equals("yes") ? true : false; +// } +// String cache = features.get(CLEAR_ALL_CACHE); +// if (cache != null) { +// clearAllCache = cache.equals("yes") ? true : false; +// } else { +// cache = features.get(CLEAR_SESSION_CACHE); +// if (cache != null) { +// clearSessionCache = cache.equals("yes") ? true : false; +// } +// } +// String shouldPause = features.get(SHOULD_PAUSE); +// if (shouldPause != null) { +// shouldPauseInAppBrowser = shouldPause.equals("yes") ? true : false; +// } +// String wideViewPort = features.get(USER_WIDE_VIEW_PORT); +// if (wideViewPort != null ) { +// useWideViewPort = wideViewPort.equals("yes") ? true : false; +// } +// String closeButtonCaptionSet = features.get(CLOSE_BUTTON_CAPTION); +// if (closeButtonCaptionSet != null) { +// closeButtonCaption = closeButtonCaptionSet; +// } +// String closeButtonColorSet = features.get(CLOSE_BUTTON_COLOR); +// if (closeButtonColorSet != null) { +// closeButtonColor = closeButtonColorSet; +// } +// String toolbarColorSet = features.get(TOOLBAR_COLOR); +// if (toolbarColorSet != null) { +// toolbarColor = android.graphics.Color.parseColor(toolbarColorSet); +// } +// String navigationButtonColorSet = features.get(NAVIGATION_COLOR); +// if (navigationButtonColorSet != null) { +// navigationButtonColor = navigationButtonColorSet; +// } +// String showFooterSet = features.get(FOOTER); +// if (showFooterSet != null) { +// showFooter = showFooterSet.equals("yes") ? true : false; +// } +// String footerColorSet = features.get(FOOTER_COLOR); +// if (footerColorSet != null) { +// footerColor = footerColorSet; +// } +// } +// +// // Create dialog in new thread +// Runnable runnable = new Runnable() { +// /** +// * Convert our DIP units to Pixels +// * +// * @return int +// */ +// private int dpToPixels(int dipValue) { +// int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, +// (float) dipValue, +// activity.getResources().getDisplayMetrics() +// ); +// +// return value; +// } +// +// @TargetApi(8) +// private View createCloseButton(int id){ +// View _close; +// Resources activityRes = activity.getResources(); +// +// if (closeButtonCaption != "") { +// // Use TextView for text +// TextView close = new TextView(activity); +// close.setText(closeButtonCaption); +// close.setTextSize(20); +// if (closeButtonColor != "") close.setTextColor(android.graphics.Color.parseColor(closeButtonColor)); +// close.setGravity(android.view.Gravity.CENTER_VERTICAL); +// close.setPadding(this.dpToPixels(10), 0, this.dpToPixels(10), 0); +// _close = close; +// } +// else { +// ImageButton close = new ImageButton(activity); +// int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", activity.getPackageName()); +// Drawable closeIcon = activityRes.getDrawable(closeResId); +// if (closeButtonColor != "") close.setColorFilter(android.graphics.Color.parseColor(closeButtonColor)); +// close.setImageDrawable(closeIcon); +// close.setScaleType(ImageView.ScaleType.FIT_CENTER); +// if (Build.VERSION.SDK_INT >= 16) +// close.getAdjustViewBounds(); +// +// _close = close; +// } +// +// RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); +// closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); +// _close.setLayoutParams(closeLayoutParams); +// +// if (Build.VERSION.SDK_INT >= 16) +// _close.setBackground(null); +// else +// _close.setBackgroundDrawable(null); +// +// _close.setContentDescription("Close Button"); +// _close.setId(Integer.valueOf(id)); +// _close.setOnClickListener(new View.OnClickListener() { +// public void onClick(View v) { +// closeDialog(); +// } +// }); +// +// return _close; +// } +// +// @SuppressLint("NewApi") +// public void run() { +// // CB-6702 InAppBrowser hangs when opening more than one instance +// if (dialog != null) { +// dialog.dismiss(); +// }; +// +// // Let's create the main dialog +// dialog = new InAppBrowserDialog(activity, android.R.style.Theme_NoTitleBar); +// dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog; +// dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); +// dialog.setCancelable(true); +// dialog.setInAppBroswer(getInAppBrowser()); +// +// int mainId = activity.getResources().getIdentifier("activity_web_view", "layout", activity.getPackageName()); +// LinearLayout main = (LinearLayout) LayoutInflater.from(registrar.context()).inflate(mainId, null); +// +// WebView webView = (WebView) main.getChildAt(1)); +// webView.loadUrl("https://www.google.com"); +// +// // Main container layout +//// LinearLayout main = new LinearLayout(activity); +//// main.setOrientation(LinearLayout.VERTICAL); +//// +//// // Toolbar layout +//// RelativeLayout toolbar = new RelativeLayout(activity); +//// //Please, no more black! +//// +//// toolbar.setBackgroundColor(toolbarColor); +//// toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44))); +//// toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2)); +//// toolbar.setHorizontalGravity(Gravity.LEFT); +//// toolbar.setVerticalGravity(Gravity.TOP); +//// +//// // Action Button Container layout +//// RelativeLayout actionButtonContainer = new RelativeLayout(activity); +//// actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); +//// actionButtonContainer.setHorizontalGravity(Gravity.LEFT); +//// actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL); +//// actionButtonContainer.setId(Integer.valueOf(1)); +//// +//// // Back button +//// ImageButton back = new ImageButton(activity); +//// RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); +//// backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT); +//// back.setLayoutParams(backLayoutParams); +//// back.setContentDescription("Back Button"); +//// back.setId(Integer.valueOf(2)); +//// Resources activityRes = activity.getResources(); +//// int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", activity.getPackageName()); +//// Drawable backIcon = activityRes.getDrawable(backResId); +//// if (navigationButtonColor != "") back.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor)); +//// if (Build.VERSION.SDK_INT >= 16) +//// back.setBackground(null); +//// else +//// back.setBackgroundDrawable(null); +//// back.setImageDrawable(backIcon); +//// back.setScaleType(ImageView.ScaleType.FIT_CENTER); +//// back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10)); +//// if (Build.VERSION.SDK_INT >= 16) +//// back.getAdjustViewBounds(); +//// +//// back.setOnClickListener(new View.OnClickListener() { +//// public void onClick(View v) { +//// goBack(); +//// } +//// }); +//// +//// // Forward button +//// ImageButton forward = new ImageButton(activity); +//// RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); +//// forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2); +//// forward.setLayoutParams(forwardLayoutParams); +//// forward.setContentDescription("Forward Button"); +//// forward.setId(Integer.valueOf(3)); +//// int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", activity.getPackageName()); +//// Drawable fwdIcon = activityRes.getDrawable(fwdResId); +//// if (navigationButtonColor != "") forward.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor)); +//// if (Build.VERSION.SDK_INT >= 16) +//// forward.setBackground(null); +//// else +//// forward.setBackgroundDrawable(null); +//// forward.setImageDrawable(fwdIcon); +//// forward.setScaleType(ImageView.ScaleType.FIT_CENTER); +//// forward.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10)); +//// if (Build.VERSION.SDK_INT >= 16) +//// forward.getAdjustViewBounds(); +//// +//// forward.setOnClickListener(new View.OnClickListener() { +//// public void onClick(View v) { +//// goForward(); +//// } +//// }); +//// +//// // Edit Text Box +//// edittext = new EditText(activity); +//// RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); +//// textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1); +//// textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5); +//// edittext.setLayoutParams(textLayoutParams); +//// edittext.setId(Integer.valueOf(4)); +//// edittext.setSingleLine(true); +//// edittext.setText(url); +//// edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI); +//// edittext.setImeOptions(EditorInfo.IME_ACTION_GO); +//// edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE +//// edittext.setOnKeyListener(new View.OnKeyListener() { +//// public boolean onKey(View v, int keyCode, KeyEvent event) { +//// // If the event is a key-down event on the "enter" button +//// if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { +//// navigate(edittext.getText().toString()); +//// return true; +//// } +//// return false; +//// } +//// }); +//// +//// +//// // Header Close/Done button +//// View close = createCloseButton(5); +//// toolbar.addView(close); +//// +//// // Footer +//// RelativeLayout footer = new RelativeLayout(activity); +//// int _footerColor; +//// if(footerColor != ""){ +//// _footerColor = Color.parseColor(footerColor); +//// }else{ +//// _footerColor = android.graphics.Color.LTGRAY; +//// } +//// footer.setBackgroundColor(_footerColor); +//// RelativeLayout.LayoutParams footerLayout = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44)); +//// footerLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE); +//// footer.setLayoutParams(footerLayout); +//// if (closeButtonCaption != "") footer.setPadding(this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8)); +//// footer.setHorizontalGravity(Gravity.LEFT); +//// footer.setVerticalGravity(Gravity.BOTTOM); +//// +//// View footerClose = createCloseButton(7); +//// footer.addView(footerClose); +//// +//// +//// // WebView +//// inAppWebView = new WebView(activity); +//// inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); +//// inAppWebView.setId(Integer.valueOf(6)); +//// inAppWebView.setWebChromeClient(new WebChromeClient() { +//// +//// @Override +//// public void onProgressChanged(WebView view, int newProgress) { +//// super.onProgressChanged(view, newProgress); +//// } +//// +//// @Override +//// public void onReceivedTitle(WebView view, String title) { +//// super.onReceivedTitle(view, title); +//// } +//// +//// @Override +//// public void onReceivedIcon(WebView view, Bitmap icon) { +//// super.onReceivedIcon(view, icon); +//// } +//// +//// // For Android 5.0+ +//// public boolean onShowFileChooser (WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) +//// { +//// Log.d(LOG_TAG, "File Chooser 5.0+"); +//// // If callback exists, finish it. +//// if(mUploadCallbackLollipop != null) { +//// mUploadCallbackLollipop.onReceiveValue(null); +//// } +//// mUploadCallbackLollipop = filePathCallback; +//// +//// // Create File Chooser Intent +//// Intent content = new Intent(Intent.ACTION_GET_CONTENT); +//// content.addCategory(Intent.CATEGORY_OPENABLE); +//// content.setType("*/*"); +//// +//// registrar.context().startActivity(Intent.createChooser(content, "Select File")); +//// return true; +//// } +//// +//// // For Android 4.1+ +//// public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) +//// { +//// Log.d(LOG_TAG, "File Chooser 4.1+"); +//// // Call file chooser for Android 3.0+ +//// openFileChooser(uploadMsg, acceptType); +//// } +//// +//// // For Android 3.0+ +//// public void openFileChooser(ValueCallback uploadMsg, String acceptType) +//// { +//// Log.d(LOG_TAG, "File Chooser 3.0+"); +//// mUploadCallback = uploadMsg; +//// Intent content = new Intent(Intent.ACTION_GET_CONTENT); +//// content.addCategory(Intent.CATEGORY_OPENABLE); +//// +//// registrar.context().startActivity(Intent.createChooser(content, "Select File")); +//// } +//// }); +//// +//// WebViewClient client = new InAppBrowserClient(edittext, activity, channel); +//// inAppWebView.setWebViewClient(client); +//// WebSettings settings = inAppWebView.getSettings(); +//// settings.setJavaScriptEnabled(true); +//// //settings.setJavaScinAppWebViewriptCanOpenWindowsAutomatically(true); +//// settings.setBuiltInZoomControls(showZoomControls); +//// settings.setPluginState(android.webkit.WebSettings.PluginState.ON); +//// +//// if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { +//// settings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture); +//// } +//// +//// String overrideUserAgent = activity.getPreferences(0).getString("OverrideUserAgent", null); +//// String appendUserAgent = activity.getPreferences(0).getString("AppendUserAgent", null); +//// +//// if (overrideUserAgent != null) { +//// settings.setUserAgentString(overrideUserAgent); +//// } +//// if (appendUserAgent != null) { +//// settings.setUserAgentString(settings.getUserAgentString() + appendUserAgent); +//// } +//// +//// //Toggle whether this is enabled or not! +//// Bundle appSettings = activity.getIntent().getExtras(); +//// boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true); +//// if (enableDatabase) { +//// String databasePath = activity.getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath(); +//// settings.setDatabasePath(databasePath); +//// settings.setDatabaseEnabled(true); +//// } +//// settings.setDomStorageEnabled(true); +//// +//// if (clearAllCache) { +//// CookieManager.getInstance().removeAllCookie(); +//// } else if (clearSessionCache) { +//// CookieManager.getInstance().removeSessionCookie(); +//// } +//// +//// // Enable Thirdparty Cookies on >=Android 5.0 device +//// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { +//// CookieManager.getInstance().setAcceptThirdPartyCookies(inAppWebView,true); +//// } +//// +//// inAppWebView.loadUrl(url); +//// inAppWebView.setId(Integer.valueOf(6)); +//// inAppWebView.getSettings().setLoadWithOverviewMode(true); +//// inAppWebView.getSettings().setUseWideViewPort(useWideViewPort); +//// inAppWebView.requestFocus(); +//// inAppWebView.requestFocusFromTouch(); +//// +//// // Add the back and forward buttons to our action button container layout +//// actionButtonContainer.addView(back); +//// actionButtonContainer.addView(forward); +//// +//// // Add the views to our toolbar if they haven't been disabled +//// if (!hideNavigationButtons) toolbar.addView(actionButtonContainer); +//// if (!hideUrlBar) toolbar.addView(edittext); +//// +//// // Don't add the toolbar if its been disabled +//// if (getShowLocationBar()) { +//// // Add our toolbar to our main view/layout +//// main.addView(toolbar); +//// } +//// +//// // Add our webview to our main view/layout +//// RelativeLayout webViewLayout = new RelativeLayout(activity); +//// webViewLayout.addView(inAppWebView); +//// main.addView(webViewLayout); +//// +//// // Don't add the footer unless it's been enabled +//// if (showFooter) { +//// webViewLayout.addView(footer); +//// } +// +// WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); +// lp.copyFrom(dialog.getWindow().getAttributes()); +// lp.width = WindowManager.LayoutParams.MATCH_PARENT; +// lp.height = WindowManager.LayoutParams.MATCH_PARENT; +// +// dialog.setContentView(main); +// dialog.show(); +// dialog.getWindow().setAttributes(lp); +// // the goal of openhidden is to load the url and not display it +// // Show() needs to be called to cause the URL to be loaded +// if(openWindowHidden) { +// dialog.hide(); +// } +// } +// }; +// this.activity.runOnUiThread(runnable); + //return ""; } /** diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java new file mode 100644 index 00000000..6d37d213 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserOptions.java @@ -0,0 +1,60 @@ +package com.pichillilorenzo.flutter_inappbrowser; + +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.util.Log; + +import java.lang.reflect.Field; +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; + +public class InAppBrowserOptions { + + boolean clearCache = false; + boolean clearSessionCache = false; + boolean spinner = true; + boolean hidden = false; + boolean toolbarTop = true; + String toolbarTopColor = "toolbarTopColor"; + boolean hideUrlBar = false; + boolean enableViewportScale = false; + boolean keyboardDisplayRequiresUserAction = true; + boolean suppressesIncrementalRendering = false; + boolean allowsAirPlayForMediaPlayback = true; + boolean mediaTypesRequiringUserActionForPlayback = true; + boolean allowsBackForwardNavigationGestures = true; + boolean allowsLinkPreview = true; + boolean ignoresViewportScaleLimits = false; + boolean allowsInlineMediaPlayback = false; + boolean allowsPictureInPictureMediaPlayback = true; + boolean javaScriptCanOpenWindowsAutomatically = false; + boolean javaScriptEnabled = true; + + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + public void parse(HashMap options) { + Iterator it = options.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry)it.next(); + try { + this.getClass().getField(pair.getKey()).set(this, pair.getValue()); + } catch (NoSuchFieldException | IllegalAccessException e) { + // silent + } + } + + } + + public HashMap getHashMap() { + HashMap options = new HashMap<>(); + for (Field f: this.getClass().getDeclaredFields()) { + try { + options.put(f.getName(), f.get(this)); + } catch (IllegalAccessException e) { + // silent + } + } + return options; + } + +} diff --git a/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java new file mode 100644 index 00000000..1396c828 --- /dev/null +++ b/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java @@ -0,0 +1,71 @@ +package com.pichillilorenzo.flutter_inappbrowser; + +import android.app.SearchManager; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.support.annotation.RequiresApi; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.webkit.WebView; +import android.widget.EditText; +import android.widget.SearchView; + +import java.util.HashMap; + +public class WebViewActivity extends AppCompatActivity { + + WebView wv; + SearchView searchView; + InAppBrowserOptions options; + + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Bundle b = getIntent().getExtras(); + String url = b.getString("url"); + + options = new InAppBrowserOptions(); + options.parse((HashMap) b.getSerializable("options")); + + setContentView(R.layout.activity_web_view); + wv = (WebView) findViewById(R.id.webView); + + InAppBrowser.webViewActivity = this; + + wv.loadUrl(url); + getSupportActionBar().setTitle(wv.getTitle()); + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + // Inflate menu to add items to action bar if it is present. + inflater.inflate(R.menu.menu_main, menu); + + searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView(); + searchView.setQuery(wv.getUrl(), false); + getSupportActionBar().setTitle(wv.getTitle()); + + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + wv.loadUrl(query); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + return false; + } + }); + + return true; + } + +} diff --git a/android/src/main/res/drawable-hdpi/ic_action_next_item.png b/android/src/main/res/drawable-hdpi/ic_action_next_item.png deleted file mode 100755 index fa469d88..00000000 Binary files a/android/src/main/res/drawable-hdpi/ic_action_next_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-hdpi/ic_action_previous_item.png b/android/src/main/res/drawable-hdpi/ic_action_previous_item.png deleted file mode 100755 index e861ecce..00000000 Binary files a/android/src/main/res/drawable-hdpi/ic_action_previous_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-hdpi/ic_action_remove.png b/android/src/main/res/drawable-hdpi/ic_action_remove.png deleted file mode 100755 index f889617e..00000000 Binary files a/android/src/main/res/drawable-hdpi/ic_action_remove.png and /dev/null differ diff --git a/android/src/main/res/drawable-mdpi/ic_action_next_item.png b/android/src/main/res/drawable-mdpi/ic_action_next_item.png deleted file mode 100755 index 47365a30..00000000 Binary files a/android/src/main/res/drawable-mdpi/ic_action_next_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-mdpi/ic_action_previous_item.png b/android/src/main/res/drawable-mdpi/ic_action_previous_item.png deleted file mode 100755 index 4ad2df42..00000000 Binary files a/android/src/main/res/drawable-mdpi/ic_action_previous_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-mdpi/ic_action_remove.png b/android/src/main/res/drawable-mdpi/ic_action_remove.png deleted file mode 100755 index e84853e4..00000000 Binary files a/android/src/main/res/drawable-mdpi/ic_action_remove.png and /dev/null differ diff --git a/android/src/main/res/drawable-xhdpi/ic_action_next_item.png b/android/src/main/res/drawable-xhdpi/ic_action_next_item.png deleted file mode 100755 index 5f304742..00000000 Binary files a/android/src/main/res/drawable-xhdpi/ic_action_next_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-xhdpi/ic_action_previous_item.png b/android/src/main/res/drawable-xhdpi/ic_action_previous_item.png deleted file mode 100755 index ed8ac91d..00000000 Binary files a/android/src/main/res/drawable-xhdpi/ic_action_previous_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-xhdpi/ic_action_remove.png b/android/src/main/res/drawable-xhdpi/ic_action_remove.png deleted file mode 100755 index 4cd0458b..00000000 Binary files a/android/src/main/res/drawable-xhdpi/ic_action_remove.png and /dev/null differ diff --git a/android/src/main/res/drawable-xxhdpi/ic_action_next_item.png b/android/src/main/res/drawable-xxhdpi/ic_action_next_item.png deleted file mode 100755 index 51479d8d..00000000 Binary files a/android/src/main/res/drawable-xxhdpi/ic_action_next_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-xxhdpi/ic_action_previous_item.png b/android/src/main/res/drawable-xxhdpi/ic_action_previous_item.png deleted file mode 100755 index bc8ff124..00000000 Binary files a/android/src/main/res/drawable-xxhdpi/ic_action_previous_item.png and /dev/null differ diff --git a/android/src/main/res/drawable-xxhdpi/ic_action_remove.png b/android/src/main/res/drawable-xxhdpi/ic_action_remove.png deleted file mode 100755 index 331c545b..00000000 Binary files a/android/src/main/res/drawable-xxhdpi/ic_action_remove.png and /dev/null differ diff --git a/android/src/main/res/drawable/ic_more_vert_black_24dp.xml b/android/src/main/res/drawable/ic_more_vert_black_24dp.xml new file mode 100644 index 00000000..5176d8a4 --- /dev/null +++ b/android/src/main/res/drawable/ic_more_vert_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/src/main/res/layout/activity_web_view.xml b/android/src/main/res/layout/activity_web_view.xml new file mode 100644 index 00000000..d1bb58d2 --- /dev/null +++ b/android/src/main/res/layout/activity_web_view.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/android/src/main/res/menu/menu_main.xml b/android/src/main/res/menu/menu_main.xml new file mode 100644 index 00000000..6f4d5ade --- /dev/null +++ b/android/src/main/res/menu/menu_main.xml @@ -0,0 +1,18 @@ + + + + + + + + diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml new file mode 100644 index 00000000..c9199621 --- /dev/null +++ b/android/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + + Settings + Search + diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml new file mode 100644 index 00000000..9e82c07e --- /dev/null +++ b/android/src/main/res/values/styles.xml @@ -0,0 +1,6 @@ + + + + diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 6efe3fa3..cc2201a7 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -34,7 +34,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.pichillilorenzo.flutter_inappbrowserexample" - minSdkVersion 16 + minSdkVersion 17 targetSdkVersion 27 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/example/ios/Runner/WebView.storyboard b/example/ios/Runner/WebView.storyboard index 125c7877..bc1d47c2 100644 --- a/example/ios/Runner/WebView.storyboard +++ b/example/ios/Runner/WebView.storyboard @@ -22,7 +22,7 @@ - + diff --git a/example/lib/main.dart b/example/lib/main.dart index bc5b063a..dc572a22 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -18,6 +18,7 @@ class MyInAppBrowser extends InAppBrowser { this.injectScriptCode(""" \$( "body" ).html( "Next Step..." ) """); + this.injectStyleCode(""" body { background-color: #3c3c3c !important; diff --git a/ios/Classes/InAppBrowserOptions.swift b/ios/Classes/InAppBrowserOptions.swift index 01ff0bfc..d3cc2f32 100644 --- a/ios/Classes/InAppBrowserOptions.swift +++ b/ios/Classes/InAppBrowserOptions.swift @@ -14,11 +14,6 @@ public class InAppBrowserOptions: NSObject { var clearCache = false var clearSessionCache = false var spinner = true - var enableViewportScale = false - var mediaPlaybackRequiresUserAction = false - var allowInlineMediaPlayback = false - var keyboardDisplayRequiresUserAction = true - var suppressesIncrementalRendering = false var hidden = false var disallowOverScroll = false var toolbarTop = true @@ -30,6 +25,18 @@ public class InAppBrowserOptions: NSObject { var hideUrlBar = false var presentationStyle = 0 //fullscreen var transitionStyle = 0 //crossDissolve + var enableViewportScale = false + var keyboardDisplayRequiresUserAction = true + var suppressesIncrementalRendering = false + var allowsAirPlayForMediaPlayback = true + var mediaTypesRequiringUserActionForPlayback = "none" + var allowsBackForwardNavigationGestures = true + var allowsLinkPreview = true + var ignoresViewportScaleLimits = false + var allowsInlineMediaPlayback = false + var allowsPictureInPictureMediaPlayback = true + var javaScriptCanOpenWindowsAutomatically = false + var javaScriptEnabled = true public func parse(options: [String: Any]) { for (key, value) in options { diff --git a/ios/Classes/InAppBrowserWebViewController.swift b/ios/Classes/InAppBrowserWebViewController.swift index 1411ffdb..06fa6896 100644 --- a/ios/Classes/InAppBrowserWebViewController.swift +++ b/ios/Classes/InAppBrowserWebViewController.swift @@ -131,6 +131,9 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio func prepareWebView() { + self.webView.configuration.userContentController = WKUserContentController() + self.webView.configuration.preferences = WKPreferences() + if (browserOptions?.hideUrlBar)! { self.urlField.isHidden = true self.urlField.isEnabled = false @@ -191,9 +194,6 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio } } - let wkUController = WKUserContentController() - self.webView.configuration.userContentController = wkUController - if (browserOptions?.enableViewportScale)! { let jscript = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);" let userScript = WKUserScript(source: jscript, injectionTime: .atDocumentEnd, forMainFrameOnly: true) @@ -204,18 +204,50 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio let jscriptWebkitTouchCallout = WKUserScript(source: "document.body.style.webkitTouchCallout='none';", injectionTime: .atDocumentEnd, forMainFrameOnly: true) self.webView.configuration.userContentController.addUserScript(jscriptWebkitTouchCallout) - if (browserOptions?.mediaPlaybackRequiresUserAction)! { + if (browserOptions?.mediaTypesRequiringUserActionForPlayback)! != "" { if #available(iOS 10.0, *) { - self.webView.configuration.mediaTypesRequiringUserActionForPlayback = .all + switch (browserOptions?.mediaTypesRequiringUserActionForPlayback)! { + case "all": + self.webView.configuration.mediaTypesRequiringUserActionForPlayback = .all + break + case "audio": + self.webView.configuration.mediaTypesRequiringUserActionForPlayback = .audio + break + case "video": + self.webView.configuration.mediaTypesRequiringUserActionForPlayback = .video + break + default: + self.webView.configuration.mediaTypesRequiringUserActionForPlayback = [] + break + } + } else { // Fallback on earlier versions } } - self.webView.configuration.allowsInlineMediaPlayback = (browserOptions?.allowInlineMediaPlayback)! - + self.webView.configuration.allowsInlineMediaPlayback = (browserOptions?.allowsInlineMediaPlayback)! self.webView.keyboardDisplayRequiresUserAction = browserOptions?.keyboardDisplayRequiresUserAction self.webView.configuration.suppressesIncrementalRendering = (browserOptions?.suppressesIncrementalRendering)! + self.webView.allowsBackForwardNavigationGestures = (browserOptions?.allowsBackForwardNavigationGestures)! + if #available(iOS 9.0, *) { + self.webView.allowsLinkPreview = (browserOptions?.allowsLinkPreview)! + } else { + // Fallback on earlier versions + } + if #available(iOS 10.0, *) { + self.webView.configuration.ignoresViewportScaleLimits = (browserOptions?.ignoresViewportScaleLimits)! + } else { + // Fallback on earlier versions + } + self.webView.configuration.allowsInlineMediaPlayback = (browserOptions?.allowsInlineMediaPlayback)! + if #available(iOS 9.0, *) { + self.webView.configuration.allowsPictureInPictureMediaPlayback = (browserOptions?.allowsPictureInPictureMediaPlayback)! + } else { + // Fallback on earlier versions + } + self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = (browserOptions?.javaScriptCanOpenWindowsAutomatically)! + self.webView.configuration.preferences.javaScriptEnabled = (browserOptions?.javaScriptEnabled)! } // Load user requested url @@ -233,189 +265,11 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio return false } - // func createViews() { - // // We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included - //// let screenSize: CGRect = view.bounds - //// let myView = UIView(frame: CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height-44-CGFloat((browserOptions?.location)! ? FOOTER_HEIGHT : TOOLBAR_HEIGHT))) - //// - // - //// - //// let webViewFrame = CGRect(x: 0, y: urlField.frame.height, width: screenSize.width, height: screenSize.height-44-CGFloat((browserOptions?.location)! ? FOOTER_HEIGHT : TOOLBAR_HEIGHT)) - //// - //// let webConfiguration = WKWebViewConfiguration() - //// webView = WKWebView(frame: webViewFrame, configuration: webConfiguration) - //// webView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] - // - // let toolbarIsAtBottom: Bool = browserOptions!.toolbarposition == kInAppBrowserToolbarBarPositionBottom - // - // var webViewBounds: CGRect = view.bounds - // webViewBounds.origin.y += (toolbarIsAtBottom) ? 0 : CGFloat(TOOLBAR_HEIGHT+getStatusBarOffset()) - // webViewBounds.size.height -= (browserOptions?.location)! ? CGFloat(TOOLBAR_HEIGHT+getStatusBarOffset()) : 0 - // let webConfiguration = WKWebViewConfiguration() - // webView = WKWebView(frame: webViewBounds, configuration: webConfiguration) - // webView?.autoresizingMask = [.flexibleWidth, .flexibleHeight] - // view.addSubview(webView!) - // //view.sendSubview(toBack: webView!) - // - // webView?.uiDelegate = self - // webView?.navigationDelegate = self - // webView?.backgroundColor = UIColor.white - // webView?.clearsContextBeforeDrawing = true - // webView?.clipsToBounds = true - // webView?.contentMode = .scaleToFill - // webView?.isMultipleTouchEnabled = true - // webView?.isOpaque = true - // //webView?.scalesPageToFit = false - // webView?.isUserInteractionEnabled = true - // - // spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray) - // spinner.alpha = 1.000 - // spinner.autoresizesSubviews = true - // spinner.autoresizingMask = [.flexibleLeftMargin, .flexibleTopMargin, .flexibleBottomMargin, .flexibleRightMargin] - // spinner.clearsContextBeforeDrawing = false - // spinner.clipsToBounds = false - // spinner.contentMode = .scaleToFill - // spinner.frame = CGRect(x: (webView?.frame.midX)!, y: (webView?.frame.midY)!, width: 20.0, height: 20.0) - // spinner.isHidden = false - // spinner.hidesWhenStopped = true - // spinner.isMultipleTouchEnabled = false - // spinner.isOpaque = false - // spinner.isUserInteractionEnabled = false - // spinner.stopAnimating() - // - // closeButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.close)) - // closeButton.isEnabled = true - // let flexibleSpaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) - // let fixedSpaceButton = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) - // fixedSpaceButton.width = 20 - // - // - // let toolbarY: Float = toolbarIsAtBottom ? Float(view.bounds.size.height) - TOOLBAR_HEIGHT : 0.0 - // let toolbarFrame = CGRect(x: 0.0, y: CGFloat(toolbarY), width: view.bounds.size.width, height: CGFloat(TOOLBAR_HEIGHT)) - // - // toolbar = UIToolbar(frame: toolbarFrame) - // toolbar.alpha = 1.000 - // toolbar.autoresizesSubviews = true - // toolbar.autoresizingMask = toolbarIsAtBottom ? ([.flexibleWidth, .flexibleTopMargin]) : .flexibleWidth - // toolbar.barStyle = .blackOpaque - // toolbar.clearsContextBeforeDrawing = false - // toolbar.clipsToBounds = false - // toolbar.contentMode = .scaleToFill - // toolbar.isHidden = false - // toolbar.isMultipleTouchEnabled = false - // toolbar.isOpaque = false - // toolbar.isUserInteractionEnabled = true - // if browserOptions?.toolbarcolor != nil { - // // Set toolbar color if user sets it in options - // toolbar.barTintColor = color(fromHexString: (browserOptions?.toolbarcolor)!) - // } - // if !(browserOptions?.toolbartranslucent)! { - // // Set toolbar translucent to no if user sets it in options - // toolbar.isTranslucent = false - // } - // let labelInset: CGFloat = 5.0 - // let locationBarY: Float = toolbarIsAtBottom ? Float(view.bounds.size.height) - FOOTER_HEIGHT : Float(view.bounds.size.height) - LOCATIONBAR_HEIGHT - // - // - // let frontArrowString = NSLocalizedString("►", comment: "") - // // create arrow from Unicode char - // forwardButton = UIBarButtonItem(title: frontArrowString, style: .plain, target: self, action: #selector(self.goForward)) - // - // //forwardButton = UIBarButtonItem(barButtonSystemItem: .fastForward, target: self, action: #selector(self.goForward)) - // forwardButton.isEnabled = true - // forwardButton.imageInsets = UIEdgeInsets.zero as? UIEdgeInsets ?? UIEdgeInsets() - // if browserOptions?.navigationbuttoncolor != nil { - // // Set button color if user sets it in options - // forwardButton.tintColor = color(fromHexString: (browserOptions?.navigationbuttoncolor)!) - // } - // - // let backArrowString = NSLocalizedString("◄", comment: "") - // // create arrow from Unicode char - // backButton = UIBarButtonItem(title: backArrowString, style: .plain, target: self, action: #selector(self.goBack)) - // backButton.isEnabled = true - // backButton.imageInsets = UIEdgeInsets.zero as? UIEdgeInsets ?? UIEdgeInsets() - // if browserOptions?.navigationbuttoncolor != nil { - // // Set button color if user sets it in options - // backButton.tintColor = color(fromHexString: (browserOptions?.navigationbuttoncolor)!) - // } - // - // reloadButton = UIBarButtonItem(barButtonSystemItem: .refresh, target: self, action: #selector(self.reload)) - // reloadButton.isEnabled = true - // reloadButton.imageInsets = UIEdgeInsetsMake(0, 0, 0, 15) - // - // urlField = UITextField() - // urlField.bounds.size.width = toolbar.bounds.width - 150 - // urlField.bounds.size.height = CGFloat(TOOLBAR_HEIGHT-15) - // urlField.backgroundColor = color(fromHexString: "#ECECED") - // urlField.center.y = toolbar.center.y - // urlField.autoresizesSubviews = true - // urlField.autoresizingMask = [.flexibleWidth, .flexibleHeight] - // urlField.text = currentURL?.absoluteString - // urlField.textAlignment = NSTextAlignment.center - // urlField.font = UIFont.systemFont(ofSize: 15) - // urlField.borderStyle = UITextBorderStyle.roundedRect - // urlField.autocorrectionType = UITextAutocorrectionType.no - // urlField.keyboardType = UIKeyboardType.default - // urlField.returnKeyType = UIReturnKeyType.done - // urlField.clearButtonMode = UITextFieldViewMode.whileEditing; - // urlField.contentVerticalAlignment = UIControlContentVerticalAlignment.center - // urlField.delegate = self - // urlFieldBarButton = UIBarButtonItem.init(customView: urlField) - // - // // Filter out Navigation Buttons if user requests so - // if (browserOptions?.hidenavigationbuttons)! { - // toolbar.items = [closeButton, flexibleSpaceButton, urlFieldBarButton] - // } - // else { - // //toolbar.items = [urlFieldBarButton, closeButton, flexibleSpaceButton, backButton, fixedSpaceButton, forwardButton] - // toolbar.items = [urlFieldBarButton, flexibleSpaceButton, reloadButton, closeButton] - // } - // - // view.backgroundColor = UIColor.gray - // view.addSubview(toolbar) - // view.addSubview(spinner) - // } - func setWebViewFrame(_ frame: CGRect) { print("Setting the WebView's frame to \(NSStringFromCGRect(frame))") webView.frame = frame } - // func showToolBar(_ show: Bool, toolbarPosition: String) { - // var toolbarFrame: CGRect = toolbar.frame - // // prevent double show/hide - // if show == !toolbar.isHidden { - // return - // } - // if show { - // toolbar.isHidden = false - // var webViewBounds: CGRect = view.bounds - // - // webViewBounds.size.height -= CGFloat(TOOLBAR_HEIGHT) - // toolbar.frame = toolbarFrame - // - // if (toolbarPosition == kInAppBrowserToolbarBarPositionTop) { - // toolbarFrame.origin.y = 0 - // webViewBounds.origin.y += toolbarFrame.size.height - // setWebViewFrame(webViewBounds) - // } - // else { - // toolbarFrame.origin.y = webViewBounds.size.height + CGFloat(LOCATIONBAR_HEIGHT) - // } - // setWebViewFrame(webViewBounds) - // } - // else { - // toolbar.isHidden = true - // setWebViewFrame(view.bounds) - // } - // } - - // override func viewDidUnload() { - // webView?.loadHTMLString(nil, baseURL: nil) - // CDVUserAgentUtil.releaseLock(userAgentLockToken) - // super.viewDidUnload() - // } - @objc func reload () { webView.reload() } @@ -431,9 +285,7 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio if (navigationDelegate != nil) { navigationDelegate?.browserExit() } - // if (navigationDelegate != nil) && navigationDelegate?.responds(to: #selector(self.browserExit)) { - // navigationDelegate?.browserExit() - // } + weak var weakSelf = self // Run later to avoid the "took a long time" log message. @@ -460,14 +312,18 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio webView.load(request) } - @objc func goBack(_ sender: Any) { - webView.goBack() - updateUrlTextField(url: (webView?.url?.absoluteString)!) + @objc func goBack() { + if webView.canGoBack { + webView.goBack() + updateUrlTextField(url: (webView?.url?.absoluteString)!) + } } - @objc func goForward(_ sender: Any) { - webView.goForward() - updateUrlTextField(url: (webView?.url?.absoluteString)!) + @objc func goForward() { + if webView.canGoForward { + webView.goForward() + updateUrlTextField(url: (webView?.url?.absoluteString)!) + } } func updateUrlTextField(url: String) { @@ -486,13 +342,6 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio return statusBarOffset } - // func rePositionViews() { - // if (browserOptions?.toolbarposition == kInAppBrowserToolbarBarPositionTop) { - // webView?.frame = CGRect(x: (webView?.frame.origin.x)!, y: CGFloat(TOOLBAR_HEIGHT+getStatusBarOffset()), width: (webView?.frame.size.width)!, height: (webView?.frame.size.height)!) - // toolbar.frame = CGRect(x: toolbar.frame.origin.x, y: CGFloat(getStatusBarOffset()), width: toolbar.frame.size.width, height: toolbar.frame.size.height) - // } - // } - // Helper function to convert hex color string to UIColor // Assumes input like "#00FF00" (#RRGGBB). // Taken from https://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string @@ -522,11 +371,25 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio return hexInt } + func webView(_ webView: WKWebView, + decidePolicyFor navigationAction: WKNavigationAction, + decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { + + let url = navigationAction.request.url + + if url != nil && (navigationAction.navigationType == .linkActivated || navigationAction.navigationType == .backForward) { + currentURL = url + updateUrlTextField(url: (url?.absoluteString)!) + } + + decisionHandler(.allow) + } + func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { // loading url, start spinner, update back/forward backButton.isEnabled = webView.canGoBack forwardButton.isEnabled = webView.canGoForward - + if (browserOptions?.spinner)! { spinner.startAnimating() } @@ -534,15 +397,6 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio return (navigationDelegate?.webViewDidStartLoad(webView))! } - // func webView(_ theWebView: WKWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { - // let isTopLevelNavigation: Bool? = request.url == request.mainDocumentURL - // if isTopLevelNavigation ?? false { - // currentURL = request.url - // } - // - // return (navigationDelegate?.webView(theWebView, shouldStartLoadWith: request, navigationType: navigationType))! - // } - func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { //func webViewDidFinishLoad(_ theWebView: WKWebView) { // update url, stop spinner, update back/forward diff --git a/ios/Classes/SwiftFlutterPlugin.swift b/ios/Classes/SwiftFlutterPlugin.swift index 6e26cb4c..95b7b263 100644 --- a/ios/Classes/SwiftFlutterPlugin.swift +++ b/ios/Classes/SwiftFlutterPlugin.swift @@ -59,6 +59,25 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin { self.hide() result(true) break + case "reload": + self.webViewController?.reload() + result(true) + break + case "goBack": + self.webViewController?.goBack() + result(true) + break + case "goForward": + self.webViewController?.goForward() + result(true) + break + case "isLoading": + result(self.webViewController?.webView.isLoading == true) + break + case "stopLoading": + self.webViewController?.webView.stopLoading() + result(true) + break case "injectScriptCode": self.injectScriptCode(arguments: arguments!) result(true) diff --git a/lib/flutter_inappbrowser.dart b/lib/flutter_inappbrowser.dart index c8836a45..e5b4194b 100644 --- a/lib/flutter_inappbrowser.dart +++ b/lib/flutter_inappbrowser.dart @@ -144,6 +144,31 @@ class InAppBrowser { return await _channel.invokeMethod('close'); } + ///Reloads the [InAppBrowser] window. + Future reload() async { + return await _channel.invokeMethod('reload'); + } + + ///Goes back in the history of the [InAppBrowser] window. + Future goBack() async { + return await _channel.invokeMethod('goBack'); + } + + ///Goes forward in the history of the [InAppBrowser] window. + Future goForward() async { + return await _channel.invokeMethod('goForward'); + } + + ///Check if the Web View of the [InAppBrowser] instance is in a loading state. + Future isLoading() async { + return await _channel.invokeMethod('isLoading'); + } + + ///Stops the Web View of the [InAppBrowser] instance from loading. + Future stopLoading() async { + return await _channel.invokeMethod('stopLoading'); + } + ///Injects JavaScript code into the [InAppBrowser] window. (Only available when the target is set to `_blank` or to `_self`) Future injectScriptCode(String source) async { Map args = {};