updated onLoadResource method, InAppBrowser.open url parameter has the default value: 'about:blank'

This commit is contained in:
pichillilorenzo 2018-10-13 03:16:08 +02:00
parent d696ed1e68
commit b4e3e73bce
8 changed files with 252 additions and 124 deletions

View File

@ -16,18 +16,13 @@
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment=""> <list default="true" id="9b41f7a2-a71e-4923-91fb-249d7815b3e7" name="Default" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/android/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/android/build.gradle" afterDir="false" />
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowserWebViewClient.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/WebViewActivity.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/project.pbxproj" afterDir="false" />
<change beforePath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme" afterDir="false" />
<change beforePath="$PROJECT_DIR$/example/ios/Runner/WebView.storyboard" beforeDir="false" afterPath="$PROJECT_DIR$/example/ios/Runner/WebView.storyboard" afterDir="false" />
<change beforePath="$PROJECT_DIR$/example/lib/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" afterDir="false" /> <change beforePath="$PROJECT_DIR$/example/lib/main.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/main.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserOptions.swift" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/InAppBrowserWebViewController.swift" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ios/Classes/MyURLProtocol.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/MyURLProtocol.swift" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" /> <change beforePath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" beforeDir="false" afterPath="$PROJECT_DIR$/ios/Classes/SwiftFlutterPlugin.swift" afterDir="false" />
<change beforePath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterDir="false" /> <change beforePath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pubspec.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/pubspec.yaml" afterDir="false" />
</list> </list>
<ignored path="$PROJECT_DIR$/.dart_tool/" /> <ignored path="$PROJECT_DIR$/.dart_tool/" />
<ignored path="$PROJECT_DIR$/.idea/" /> <ignored path="$PROJECT_DIR$/.idea/" />
@ -44,11 +39,14 @@
</component> </component>
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300"> <leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="true"> <file leaf-file-name="flutter_inappbrowser.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart"> <entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="358"> <state relative-caret-position="315">
<caret line="262" column="75" selection-start-line="262" selection-start-column="75" selection-end-line="262" selection-end-column="75" /> <caret line="246" column="71" selection-start-line="246" selection-start-column="71" selection-end-line="246" selection-end-column="71" />
<folding>
<element signature="e#814#834#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
@ -97,11 +95,11 @@
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="main.dart" pinned="false" current-in-tab="false"> <file leaf-file-name="main.dart" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/example/lib/main.dart"> <entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="200"> <state relative-caret-position="537">
<caret line="74" column="60" selection-start-line="74" selection-start-column="54" selection-end-line="74" selection-end-column="60" /> <caret line="140" column="44" selection-start-line="140" selection-start-column="44" selection-end-line="140" selection-end-column="64" />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -182,12 +180,12 @@
<option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java" /> <option value="$PROJECT_DIR$/android/src/main/java/com/pichillilorenzo/flutter_inappbrowser/InAppBrowser.java" />
<option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" /> <option value="$PROJECT_DIR$/ios/flutter_inappbrowser.podspec" />
<option value="$PROJECT_DIR$/example/ios/Podfile" /> <option value="$PROJECT_DIR$/example/ios/Podfile" />
<option value="$PROJECT_DIR$/pubspec.yaml" />
<option value="$PROJECT_DIR$/CHANGELOG.md" /> <option value="$PROJECT_DIR$/CHANGELOG.md" />
<option value="$PROJECT_DIR$/README.md" /> <option value="$PROJECT_DIR$/README.md" />
<option value="$PROJECT_DIR$/android/build.gradle" /> <option value="$PROJECT_DIR$/android/build.gradle" />
<option value="$PROJECT_DIR$/example/lib/main.dart" />
<option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" /> <option value="$PROJECT_DIR$/lib/flutter_inappbrowser.dart" />
<option value="$PROJECT_DIR$/pubspec.yaml" />
<option value="$PROJECT_DIR$/example/lib/main.dart" />
</list> </list>
</option> </option>
</component> </component>
@ -203,8 +201,19 @@
<foldersAlwaysOnTop value="true" /> <foldersAlwaysOnTop value="true" />
</navigator> </navigator>
<panes> <panes>
<pane id="PackagesPane" />
<pane id="AndroidView" /> <pane id="AndroidView" />
<pane id="Scope">
<subPane subId="Project Files">
<expand>
<path>
<item name="Root" type="cbb8eebc:String" user="Root" />
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="PackagesPane" />
<pane id="ProjectPane"> <pane id="ProjectPane">
<subPane> <subPane>
<expand> <expand>
@ -232,17 +241,6 @@
</subPane> </subPane>
<option name="show-excluded-files" value="false" /> <option name="show-excluded-files" value="false" />
</pane> </pane>
<pane id="Scope">
<subPane subId="Project Files">
<expand>
<path>
<item name="Root" type="cbb8eebc:String" user="Root" />
<item name="flutter_inappbrowser" type="cbb8eebc:String" user="flutter_inappbrowser" />
</path>
</expand>
<select />
</subPane>
</pane>
</panes> </panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
@ -403,15 +401,16 @@
<layout> <layout>
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" /> <window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="TODO" order="6" /> <window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="Messages" order="12" weight="0.2370452" />
<window_info anchor="right" id="Palette&#9;" order="3" /> <window_info anchor="right" id="Palette&#9;" order="3" />
<window_info id="Image Layers" order="2" /> <window_info id="Image Layers" order="2" />
<window_info id="Build Variants" order="2" side_tool="true" /> <window_info id="Build Variants" order="2" side_tool="true" />
<window_info anchor="right" id="Capture Analysis" order="3" /> <window_info anchor="right" id="Capture Analysis" order="3" />
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.50316054" side_tool="true" weight="0.32083333" /> <window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5035553" side_tool="true" weight="0.25689086" />
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3290735" /> <window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.32855567" />
<window_info active="true" anchor="bottom" id="Run" order="2" sideWeight="0.49683943" visible="true" weight="0.39801544" /> <window_info anchor="bottom" id="Run" order="2" sideWeight="0.49644473" weight="0.39801544" />
<window_info anchor="bottom" id="Version Control" order="9" /> <window_info anchor="bottom" id="Version Control" order="9" />
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4973545" weight="0.25689086" /> <window_info active="true" anchor="bottom" id="Terminal" order="10" sideWeight="0.49644473" visible="true" weight="0.25689086" />
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32922077" /> <window_info anchor="right" id="Flutter Outline" order="3" weight="0.32922077" />
<window_info anchor="bottom" id="Logcat" order="11" /> <window_info anchor="bottom" id="Logcat" order="11" />
<window_info id="Captures" order="2" weight="0.32936507" /> <window_info id="Captures" order="2" weight="0.32936507" />
@ -424,7 +423,6 @@
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" /> <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
<window_info id="Favorites" order="2" side_tool="true" /> <window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32987013" /> <window_info anchor="right" id="Flutter Inspector" order="3" weight="0.32987013" />
<window_info anchor="bottom" id="Messages" order="12" visible="true" weight="0.2370452" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="right" id="Commander" order="0" weight="0.4" /> <window_info anchor="right" id="Commander" order="0" weight="0.4" />
<window_info anchor="right" id="Assistant" order="4" visible="true" weight="0.32987013" /> <window_info anchor="right" id="Assistant" order="4" visible="true" weight="0.32987013" />
@ -439,7 +437,6 @@
<window_info id="Designer" order="4" /> <window_info id="Designer" order="4" />
<window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3290735" /> <window_info anchor="bottom" id="Dart Analysis" order="14" weight="0.3290735" />
<window_info id="Build Variants" order="2" side_tool="true" /> <window_info id="Build Variants" order="2" side_tool="true" />
<window_info id="Image Layers" order="5" />
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.4973545" weight="0.32161874" /> <window_info anchor="bottom" id="Run" order="2" sideWeight="0.4973545" weight="0.32161874" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" /> <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" /> <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
@ -451,21 +448,22 @@
<window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" /> <window_info anchor="bottom" id="Android Profiler" order="7" show_stripe_button="false" />
<window_info anchor="right" id="Commander" order="0" weight="0.4" /> <window_info anchor="right" id="Commander" order="0" weight="0.4" />
<window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5026455" side_tool="true" weight="0.31735888" /> <window_info anchor="bottom" id="Event Log" order="8" sideWeight="0.5026455" side_tool="true" weight="0.31735888" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" /> <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.18376623" />
<window_info anchor="right" id="Device File Explorer" order="4" side_tool="true" /> <window_info anchor="right" id="Device File Explorer" order="4" side_tool="true" />
<window_info anchor="right" id="Flutter Outline" order="3" weight="0.32936507" /> <window_info anchor="right" id="Flutter Outline" order="3" weight="0.32936507" />
<window_info anchor="bottom" id="Logcat" order="11" /> <window_info anchor="bottom" id="Logcat" order="11" />
<window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" /> <window_info anchor="bottom" id="Dependency Viewer" order="13" weight="0.32800853" />
<window_info anchor="bottom" id="Version Control" order="9" /> <window_info anchor="bottom" id="Version Control" order="9" />
<window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4973545" visible="true" weight="0.27888888" /> <window_info anchor="bottom" id="Terminal" order="10" sideWeight="0.4973545" visible="true" weight="0.27888888" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" /> <window_info content_ui="combo" id="Project" order="0" visible="true" weight="0.18376623" />
<window_info anchor="bottom" id="Messages" order="12" weight="0.23777778" /> <window_info anchor="bottom" id="Messages" order="12" weight="0.23777778" />
<window_info anchor="bottom" id="Message" order="0" /> <window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="TODO" order="6" /> <window_info id="Image Layers" order="5" />
<window_info anchor="right" id="Palette&#9;" order="5" /> <window_info anchor="right" id="Palette&#9;" order="5" />
<window_info anchor="right" id="Theme Preview" order="7" /> <window_info anchor="right" id="Theme Preview" order="7" />
<window_info id="Structure" order="1" weight="0.24969475" /> <window_info id="Structure" order="1" weight="0.24969475" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="Find" order="1" weight="0.3290735" /> <window_info anchor="bottom" id="Find" order="1" weight="0.3290735" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.4" /> <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
</layout-to-restore> </layout-to-restore>
@ -667,13 +665,6 @@
<state relative-caret-position="-10645" /> <state relative-caret-position="-10645" />
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="30">
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ios/flutter_inappbrowser.podspec"> <entry file="file://$PROJECT_DIR$/ios/flutter_inappbrowser.podspec">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="240"> <state relative-caret-position="240">
@ -682,6 +673,11 @@
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/README.md"> <entry file="file://$PROJECT_DIR$/README.md">
<provider editor-type-id="text-editor">
<state relative-caret-position="247">
<caret line="19" column="15" selection-start-line="19" selection-start-column="3" selection-end-line="19" selection-end-column="15" />
</state>
</provider>
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]"> <provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SPLIT"> <state split_layout="SPLIT">
<first_editor relative-caret-position="2820"> <first_editor relative-caret-position="2820">
@ -692,13 +688,13 @@
</second_editor> </second_editor>
</state> </state>
</provider> </provider>
<provider editor-type-id="text-editor">
<state relative-caret-position="247">
<caret line="19" column="15" selection-start-line="19" selection-start-column="3" selection-end-line="19" selection-end-column="15" />
</state>
</provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/CHANGELOG.md"> <entry file="file://$PROJECT_DIR$/CHANGELOG.md">
<provider editor-type-id="text-editor">
<state relative-caret-position="30">
<caret line="2" column="69" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="73" />
</state>
</provider>
<provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]"> <provider selected="true" editor-type-id="split-provider[text-editor;MarkdownPreviewEditor]">
<state split_layout="SPLIT"> <state split_layout="SPLIT">
<first_editor /> <first_editor />
@ -707,11 +703,6 @@
</second_editor> </second_editor>
</state> </state>
</provider> </provider>
<provider editor-type-id="text-editor">
<state relative-caret-position="30">
<caret line="2" column="69" lean-forward="true" selection-start-line="2" selection-start-column="2" selection-end-line="2" selection-end-column="73" />
</state>
</provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/android/settings.gradle"> <entry file="file://$PROJECT_DIR$/android/settings.gradle">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
@ -730,13 +721,6 @@
<state /> <state />
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/android/build.gradle">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="262">
<caret line="34" column="5" selection-start-line="34" selection-start-column="5" selection-end-line="34" selection-end-column="5" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib/core/string.dart"> <entry file="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib/core/string.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="173"> <state relative-caret-position="173">
@ -744,17 +728,34 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/example/lib/main.dart"> <entry file="file://$PROJECT_DIR$/android/build.gradle">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="200"> <state relative-caret-position="262">
<caret line="74" column="60" selection-start-line="74" selection-start-column="54" selection-end-line="74" selection-end-column="60" /> <caret line="34" column="5" selection-start-line="34" selection-start-column="5" selection-end-line="34" selection-end-column="5" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="30">
<caret line="2" column="14" selection-start-line="2" selection-start-column="14" selection-end-line="2" selection-end-column="14" />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart"> <entry file="file://$PROJECT_DIR$/lib/flutter_inappbrowser.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="358"> <state relative-caret-position="315">
<caret line="262" column="75" selection-start-line="262" selection-start-column="75" selection-end-line="262" selection-end-column="75" /> <caret line="246" column="71" selection-start-line="246" selection-start-column="71" selection-end-line="246" selection-end-column="71" />
<folding>
<element signature="e#814#834#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/example/lib/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="537">
<caret line="140" column="44" selection-start-line="140" selection-start-column="44" selection-end-line="140" selection-end-column="64" />
</state> </state>
</provider> </provider>
</entry> </entry>

View File

@ -1,37 +1,28 @@
package com.pichillilorenzo.flutter_inappbrowser; package com.pichillilorenzo.flutter_inappbrowser;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.net.http.SslError; import android.net.http.SslError;
import android.os.Build; import android.os.Build;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.webkit.CookieManager; import android.webkit.CookieManager;
import android.webkit.CookieSyncManager; import android.webkit.CookieSyncManager;
import android.webkit.HttpAuthHandler; import android.webkit.HttpAuthHandler;
import android.webkit.MimeTypeMap;
import android.webkit.SslErrorHandler; import android.webkit.SslErrorHandler;
import android.webkit.WebResourceRequest; import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse; import android.webkit.WebResourceResponse;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@ -278,28 +269,55 @@ public class InAppBrowserWebViewClient extends WebViewClient {
Request mRequest = new Request.Builder().url(url).build(); Request mRequest = new Request.Builder().url(url).build();
try { try {
long loadingTime = System.currentTimeMillis();
Response response = activity.httpClient.newCall(mRequest).execute(); Response response = activity.httpClient.newCall(mRequest).execute();
loadingTime = System.currentTimeMillis() - loadingTime;
String reasonPhrase = response.message(); String reasonPhrase = response.message();
if (reasonPhrase.equals("")) { if (reasonPhrase.equals("")) {
reasonPhrase = statusCodeMapping.get(response.code()); reasonPhrase = statusCodeMapping.get(response.code());
Log.d(LOG_TAG, reasonPhrase);
} }
reasonPhrase = (reasonPhrase.equals("") || reasonPhrase == null) ? "OK" : reasonPhrase; reasonPhrase = (reasonPhrase.equals("") || reasonPhrase == null) ? "OK" : reasonPhrase;
Map<String, String> headers = new HashMap<String, String>(); Map<String, String> headersResponse = new HashMap<String, String>();
for (Map.Entry<String, List<String>> entry : response.headers().toMultimap().entrySet()) { for (Map.Entry<String, List<String>> entry : response.headers().toMultimap().entrySet()) {
String value = ""; String value = "";
for (String val: entry.getValue()) { for (String val: entry.getValue()) {
value += (value == "") ? val : "; " + val; value += (value == "") ? val : "; " + val;
} }
headers.put(entry.getKey().toLowerCase(), value); headersResponse.put(entry.getKey().toLowerCase(), value);
}
Map<String, String> headersRequest = new HashMap<String, String>();
for (Map.Entry<String, List<String>> entry : mRequest.headers().toMultimap().entrySet()) {
String value = "";
for (String val: entry.getValue()) {
value += (value == "") ? val : "; " + val;
}
headersRequest.put(entry.getKey().toLowerCase(), value);
} }
Map<String, Object> obj = new HashMap<>(); Map<String, Object> obj = new HashMap<>();
Map<String, Object> res = new HashMap<>();
Map<String, Object> req = new HashMap<>();
obj.put("uuid", activity.uuid); obj.put("uuid", activity.uuid);
obj.put("url", url);
obj.put("statusCode", response.code()); byte[] dataBytes = response.body().bytes();
obj.put("headers", headers); InputStream dataStream = new ByteArrayInputStream(dataBytes);
res.put("url", url);
res.put("statusCode", response.code());
res.put("headers", headersResponse);
res.put("loadingTime", loadingTime);
res.put("data", dataBytes);
req.put("url", url);
req.put("headers", headersRequest);
req.put("method", mRequest.method());
obj.put("response", res);
obj.put("request", req);
InAppBrowserFlutterPlugin.channel.invokeMethod("onLoadResource", obj); InAppBrowserFlutterPlugin.channel.invokeMethod("onLoadResource", obj);
@ -308,8 +326,8 @@ public class InAppBrowserWebViewClient extends WebViewClient {
response.header("content-encoding"), response.header("content-encoding"),
response.code(), response.code(),
reasonPhrase, reasonPhrase,
headers, headersResponse,
response.body().byteStream() dataStream
); );
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -72,10 +72,10 @@ class MyInAppBrowser extends InAppBrowser {
} }
@override @override
void onLoadResource(String url, int statusCode, Map<String, String> headers) { void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
print("\n\n resource: $url\n\n"); print(response.loadingTime.toString() + "ms " + response.url);
print(statusCode); if (response.headers["content-length"] != null)
print(headers); print(response.headers["content-length"] + " length");
} }
@override @override
@ -138,7 +138,7 @@ class _MyAppState extends State<MyApp> {
body: new Center( body: new Center(
child: new RaisedButton(onPressed: () { child: new RaisedButton(onPressed: () {
//chromeSafariBrowser.open("https://flutter.io/"); //chromeSafariBrowser.open("https://flutter.io/");
inAppBrowserFallback.open("https://flutter.io/", options: { inAppBrowserFallback.open(url: "https://flutter.io/", options: {
//"hidden": true, //"hidden": true,
//"toolbarTopFixedTitle": "Fixed title", //"toolbarTopFixedTitle": "Fixed title",
//"useShouldOverrideUrlLoading": true //"useShouldOverrideUrlLoading": true

View File

@ -131,13 +131,8 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
URLProtocol.wk_registerScheme("http") MyURLProtocol.wkWebViewDelegateMap[uuid] = self
URLProtocol.wk_registerScheme("https")
MyURLProtocol.URLProtocolDelegate = self
URLProtocol.registerClass(MyURLProtocol.self)
webView.uiDelegate = self webView.uiDelegate = self
webView.navigationDelegate = self webView.navigationDelegate = self
@ -303,8 +298,21 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
if ((browserOptions?.userAgent)! != "") { if ((browserOptions?.userAgent)! != "") {
if #available(iOS 9.0, *) { if #available(iOS 9.0, *) {
self.webView.customUserAgent = (browserOptions?.userAgent)! self.webView.customUserAgent = (browserOptions?.userAgent)!
} else { }
// Fallback on earlier versions }
// set uuid in the User-Agent in order to know which webview is making internal requests and
// to send the onLoadResource event to the correct webview
if #available(iOS 9.0, *) {
if (self.webView.customUserAgent != nil) {
self.webView.customUserAgent = self.webView.customUserAgent! + " WKWebView/" + self.uuid
}
else {
self.webView.evaluateJavaScript("navigator.userAgent") { [weak webView] (result, error) in
if let webView = self.webView, let userAgent = result as? String {
webView.customUserAgent = userAgent + " WKWebView/" + self.uuid
}
}
} }
} }
@ -491,7 +499,6 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
func webView(_ webView: WKWebView, func webView(_ webView: WKWebView,
decidePolicyFor navigationResponse: WKNavigationResponse, decidePolicyFor navigationResponse: WKNavigationResponse,
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
//dump((navigationResponse.response as! HTTPURLResponse)) //dump((navigationResponse.response as! HTTPURLResponse))
//print(navigationResponse.response.mimeType) //print(navigationResponse.response.mimeType)
//print(navigationResponse.response.url) //print(navigationResponse.response.url)
@ -569,8 +576,8 @@ class InAppBrowserWebViewController: UIViewController, WKUIDelegate, WKNavigatio
navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error) navigationDelegate?.onLoadError(uuid: self.uuid, webView: webView, error: error)
} }
func didReceiveResponse(_ response: URLResponse, from request: URLRequest?) { func didReceiveResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, loadingTime time: Int) {
navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response) navigationDelegate?.onLoadResource(uuid: self.uuid, webView: webView, response: response, fromRequest: request, withData: data, loadingTime: time)
} }
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

View File

@ -6,29 +6,47 @@
// //
import Foundation import Foundation
import WebKit
func currentTimeInMilliSeconds() -> Int {
let currentDate = Date()
let since1970 = currentDate.timeIntervalSince1970
return Int(since1970 * 1000)
}
class MyURLProtocol: URLProtocol { class MyURLProtocol: URLProtocol {
struct Constants { // struct Constants {
static let RequestHandledKey = "URLProtocolRequestHandled" // static let RequestHandledKey = "URLProtocolRequestHandled"
} // }
var wkWebViewUuid: String?
var session: URLSession? var session: URLSession?
var sessionTask: URLSessionDataTask? var sessionTask: URLSessionDataTask?
static var URLProtocolDelegate: MyURLProtocolDelegate? var response: URLResponse?
var data: Data?
static var wkWebViewDelegateMap: [String: MyURLProtocolDelegate] = [:]
var loadingTime: Int = 0
override init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) { override init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
super.init(request: request, cachedResponse: cachedResponse, client: client) super.init(request: request, cachedResponse: cachedResponse, client: client)
if session == nil { self.wkWebViewUuid = MyURLProtocol.getUuid(request)
if session == nil && self.wkWebViewUuid != nil {
session = URLSession(configuration: .default, delegate: self, delegateQueue: nil) session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
} }
} }
override class func canInit(with request: URLRequest) -> Bool { override class func canInit(with request: URLRequest) -> Bool {
if MyURLProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil {
if getUuid(request) == nil {
return false return false
} }
// if MyURLProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil {
// return false
// }
return true return true
} }
@ -38,25 +56,54 @@ class MyURLProtocol: URLProtocol {
override func startLoading() { override func startLoading() {
let newRequest = ((request as NSURLRequest).mutableCopy() as? NSMutableURLRequest)! let newRequest = ((request as NSURLRequest).mutableCopy() as? NSMutableURLRequest)!
MyURLProtocol.setProperty(true, forKey: Constants.RequestHandledKey, in: newRequest) loadingTime = currentTimeInMilliSeconds()
//MyURLProtocol.setProperty(true, forKey: Constants.RequestHandledKey, in: newRequest)
sessionTask = session?.dataTask(with: newRequest as URLRequest) sessionTask = session?.dataTask(with: newRequest as URLRequest)
sessionTask?.resume() sessionTask?.resume()
} }
override func stopLoading() { override func stopLoading() {
if let uuid = self.wkWebViewUuid {
if MyURLProtocol.wkWebViewDelegateMap[uuid] != nil && self.response != nil {
loadingTime = currentTimeInMilliSeconds() - loadingTime
if self.data == nil {
self.data = Data()
}
MyURLProtocol.wkWebViewDelegateMap[uuid]!.didReceiveResponse(self.response!, fromRequest: request, withData: self.data!, loadingTime: loadingTime)
}
}
sessionTask?.cancel() sessionTask?.cancel()
} }
class func getUuid(_ request: URLRequest?) -> String? {
let userAgent: String? = request?.allHTTPHeaderFields?["User-Agent"]
var uuid: String? = nil
if userAgent != nil {
if userAgent!.contains("WKWebView/") {
let userAgentSplitted = userAgent!.split(separator: " ")
uuid = String(userAgentSplitted[userAgentSplitted.count-1]).replacingOccurrences(of: "WKWebView/", with: "")
}
}
return uuid
}
} }
extension MyURLProtocol: URLSessionDataDelegate { extension MyURLProtocol: URLSessionDataDelegate {
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
if self.data == nil {
self.data = data
}
else {
self.data!.append(data)
}
client?.urlProtocol(self, didLoad: data) client?.urlProtocol(self, didLoad: data)
} }
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
let policy = URLCache.StoragePolicy(rawValue: request.cachePolicy.rawValue) ?? .notAllowed let policy = URLCache.StoragePolicy(rawValue: request.cachePolicy.rawValue) ?? .notAllowed
self.response = response
client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: policy) client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: policy)
MyURLProtocol.URLProtocolDelegate?.didReceiveResponse(response, from: dataTask.currentRequest)
completionHandler(.allow) completionHandler(.allow)
} }
@ -98,5 +145,5 @@ extension MyURLProtocol: URLSessionDataDelegate {
} }
protocol MyURLProtocolDelegate { protocol MyURLProtocolDelegate {
func didReceiveResponse(_ response: URLResponse, from request: URLRequest?) func didReceiveResponse(_ response: URLResponse, fromRequest request: URLRequest?, withData data: Data, loadingTime time: Int)
} }

View File

@ -46,6 +46,9 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
} }
public static func register(with registrar: FlutterPluginRegistrar) { public static func register(with registrar: FlutterPluginRegistrar) {
URLProtocol.wk_registerScheme("http")
URLProtocol.wk_registerScheme("https")
URLProtocol.registerClass(MyURLProtocol.self)
let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger()) let channel = FlutterMethodChannel(name: "com.pichillilorenzo/flutter_inappbrowser", binaryMessenger: registrar.messenger())
let instance = SwiftFlutterPlugin(with: registrar) let instance = SwiftFlutterPlugin(with: registrar)
registrar.addMethodCallDelegate(instance, channel: channel) registrar.addMethodCallDelegate(instance, channel: channel)
@ -489,16 +492,28 @@ public class SwiftFlutterPlugin: NSObject, FlutterPlugin {
} }
} }
func onLoadResource(uuid: String, webView: WKWebView, response: URLResponse) { func onLoadResource(uuid: String, webView: WKWebView, response: URLResponse, fromRequest request: URLRequest?, withData data: Data, loadingTime time: Int) {
if self.webViewControllers[uuid] != nil { if self.webViewControllers[uuid] != nil {
var headers = (response as! HTTPURLResponse).allHeaderFields as! [String: String] var headersResponse = (response as! HTTPURLResponse).allHeaderFields as! [String: String]
headers.lowercaseKeys() headersResponse.lowercaseKeys()
var headersRequest = request!.allHTTPHeaderFields! as [String: String]
headersRequest.lowercaseKeys()
let arguments: [String : Any] = [ let arguments: [String : Any] = [
"uuid": uuid, "uuid": uuid,
"url": response.url?.absoluteString ?? "", "response": [
"statusCode": (response as! HTTPURLResponse).statusCode, "url": response.url!.absoluteString,
"headers": headers "statusCode": (response as! HTTPURLResponse).statusCode,
"headers": headersResponse,
"loadingTime": time,
"data": data
],
"request": [
"url": request!.url!.absoluteString,
"headers": headersRequest,
"method": request!.httpMethod!
]
] ]
channel.invokeMethod("onLoadResource", arguments: arguments) channel.invokeMethod("onLoadResource", arguments: arguments)
} }

View File

@ -21,6 +21,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
import 'dart:typed_data';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@ -34,6 +35,28 @@ enum ConsoleMessageLevel {
DEBUG, ERROR, LOG, TIP, WARNING DEBUG, ERROR, LOG, TIP, WARNING
} }
class WebResourceRequest {
String url;
Map<String, String> headers;
String method;
WebResourceRequest(this.url, this.headers, this.method);
}
class WebResourceResponse {
String url;
Map<String, String> headers;
int statusCode;
int loadingTime;
Uint8List data;
WebResourceResponse(this.url, this.headers, this.statusCode, this.loadingTime, this.data);
}
///Public class representing a JavaScript console message from WebCore. ///Public class representing a JavaScript console message from WebCore.
///This could be a issued by a call to one of the console logging functions (e.g. console.log('...')) or a JavaScript error on the page. ///This could be a issued by a call to one of the console logging functions (e.g. console.log('...')) or a JavaScript error on the page.
/// ///
@ -107,10 +130,27 @@ class InAppBrowser {
shouldOverrideUrlLoading(url); shouldOverrideUrlLoading(url);
break; break;
case "onLoadResource": case "onLoadResource":
String url = call.arguments["url"]; Map<dynamic, dynamic> rawResponse = call.arguments["response"];
int statusCode = call.arguments["statusCode"]; rawResponse = rawResponse.cast<String, dynamic>();
Map<dynamic, dynamic> headers = call.arguments["headers"]; Map<dynamic, dynamic> rawRequest = call.arguments["request"];
onLoadResource(url, statusCode, headers.cast<String, String>()); rawRequest = rawRequest.cast<String, dynamic>();
String urlResponse = rawResponse["url"];
Map<dynamic, dynamic> headersResponse = rawResponse["headers"];
headersResponse = headersResponse.cast<String, String>();
int statusCode = rawResponse["statusCode"];
int loadingTime = rawResponse["loadingTime"];
Uint8List data = rawResponse["data"];
String urlRequest = rawRequest["url"];
Map<dynamic, dynamic> headersRequest = rawRequest["headers"];
headersRequest = headersResponse.cast<String, String>();
String method = rawRequest["method"];
var response = new WebResourceResponse(urlResponse, headersResponse, statusCode, loadingTime, data);
var request = new WebResourceRequest(urlRequest, headersRequest, method);
onLoadResource(response, request);
break; break;
case "onConsoleMessage": case "onConsoleMessage":
String sourceURL = call.arguments["sourceURL"]; String sourceURL = call.arguments["sourceURL"];
@ -187,7 +227,7 @@ class InAppBrowser {
/// - __allowsInlineMediaPlayback__: Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. For this to work, add the `webkit-playsinline` attribute to any `<video>` elements. The default value is `false`. /// - __allowsInlineMediaPlayback__: Set to `true` to allow HTML5 media playback to appear inline within the screen layout, using browser-supplied controls rather than native controls. For this to work, add the `webkit-playsinline` attribute to any `<video>` elements. The default value is `false`.
/// - __allowsPictureInPictureMediaPlayback__: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`. /// - __allowsPictureInPictureMediaPlayback__: Set to `true` to allow HTML5 videos play picture-in-picture. The default value is `true`.
/// - __spinner__: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`. /// - __spinner__: Set to `false` to hide the spinner when the WebView is loading a page. The default value is `true`.
Future<void> open(String url, {Map<String, String> headers = const {}, String target = "_self", Map<String, dynamic> options = const {}}) async { Future<void> open({String url = "about:blank", Map<String, String> headers = const {}, String target = "_self", Map<String, dynamic> options = const {}}) async {
Map<String, dynamic> args = <String, dynamic>{}; Map<String, dynamic> args = <String, dynamic>{};
args.putIfAbsent('uuid', () => uuid); args.putIfAbsent('uuid', () => uuid);
args.putIfAbsent('url', () => url); args.putIfAbsent('url', () => url);
@ -328,8 +368,8 @@ class InAppBrowser {
} }
///Event fires when the [InAppBrowser] webview will load the resource specified by the given [url]. ///Event fires when the [InAppBrowser] webview will load the resource specified by the given [WebResourceRequest].
void onLoadResource(String url, int statusCode, Map<String, String> headers) { void onLoadResource(WebResourceResponse response, WebResourceRequest request) {
} }

View File

@ -1,6 +1,6 @@
name: flutter_inappbrowser name: flutter_inappbrowser
description: A Flutter plugin that allows you to open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser). description: A Flutter plugin that allows you to open an in-app browser window. (inspired by the popular cordova-plugin-inappbrowser).
version: 0.2.1 version: 0.3.0
author: Lorenzo Pichilli <pichillilorenzo@gmail.com> author: Lorenzo Pichilli <pichillilorenzo@gmail.com>
homepage: https://github.com/pichillilorenzo/flutter_inappbrowser homepage: https://github.com/pichillilorenzo/flutter_inappbrowser