0

While developing xamarin forms custom webview, when I try to load URL from assets folder, getting below error

[AndroidProtocolHandler] Unable to open asset URL: file:///android_asset/www/sf.min.js 

This is my code ChatbotView.xaml file

    <controls:HybridWebView
        x:Name="webView"
        Uri="TestWebPage.html"
        Margin="10"                  
        BackgroundColor="Red"                              
        HorizontalOptions="FillAndExpand"
        VerticalOptions="FillAndExpand" />

This is ChatbotViewModel and HybridWebView class

public class ChatbotViewModel: BaseViewModel
{
    public UrlWebViewSource SourceContent { get; set; }
    public ChatbotViewModel()
    {
        var source = new UrlWebViewSource();
        var baseUrl = DependencyService.Get<IBaseUrl>().Get();
        string filePathUrl = Path.Combine(baseUrl, "TestWebPage.html");
        source.Url = filePathUrl;
        SourceContent = source;
    }
}
public interface IBaseUrl { string Get(); }
public class HybridWebView : WebView
{
    Action<string> action;
    public static readonly BindableProperty UriProperty = BindableProperty.Create(
        propertyName: "Uri",
        returnType: typeof(string),
        declaringType: typeof(HybridWebView),
        defaultValue: default(string));
    public string Uri
    {
        get { return (string)GetValue(UriProperty); }
        set { SetValue(UriProperty, value); }
    }
    public void RegisterAction(Action<string> callback)
    {
        action = callback;
    }
    public void Cleanup()
    {
        action = null;
    }
    public void InvokeAction(string data)
    {
        if (action == null || data == null)
        {
            return;
        }
        action.Invoke(data);
    }
}

This is HybridWebViewRenderer, JavascriptWebViewClient and JSBridge class

public class HybridWebViewRenderer : WebViewRenderer
{
    const string JavascriptFunction = "function Chat1(data){jsBridge.invokeAction(data);}";
    Context _context;
    public HybridWebViewRenderer(Context context) : base(context)
    {
        _context = context;
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
    {
        base.OnElementChanged(e);
        if (e.OldElement != null)
        {
            Control.RemoveJavascriptInterface("jsBridge");
            ((HybridWebView)Element).Cleanup();
        }
        if (e.NewElement != null)
        {
            Control.SetWebViewClient(new JavascriptWebViewClient(this, $"javascript: {JavascriptFunction}"));
            Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
            Control.Settings.AllowFileAccess = true;
            Control.Settings.JavaScriptEnabled = true;
            Control.Settings.SetAppCacheMaxSize(100000000);
            Control.Settings.AllowFileAccessFromFileURLs = true;
            Control.Settings.AllowUniversalAccessFromFileURLs = true;
            Control.Settings.AllowContentAccess = true;
            Control.SetWebChromeClient(new WebChromeClient());
            Control.SetWebViewClient(new WebViewClient());
            var myUlr2 = $"file:///android_asset/TestWebPage.html";
            Control.LoadUrl(myUlr2);
        }
    }
    public class JavascriptWebViewClient : FormsWebViewClient
    {
        string _javascript;
        public JavascriptWebViewClient(HybridWebViewRenderer renderer, string javascript) : base(renderer)
        {
            _javascript = javascript;
        }
        public override void OnPageFinished(Android.Webkit.WebView view, string url)
        {
            base.OnPageFinished(view, url);
            view.EvaluateJavascript(_javascript, null);
        }
    }
    public class JSBridge : Java.Lang.Object
    {
        readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
        public JSBridge(HybridWebViewRenderer hybridRenderer)
        {
            hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
        }
        [JavascriptInterface]
        [Export("invokeAction")]
        public void InvokeAction(string data)
        {
            HybridWebViewRenderer hybridRenderer;
            if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
            {
                ((HybridWebView)hybridRenderer.Element).InvokeAction(data);
            }
        }
    }
}

Below is TestWebpage.html file. This file is accessing one of JavaScript file from assets folder

<script type='text/javascript' src='file:///android_asset/www/sf.min.js'></script>

sf.min.js is not getting loaded and throwing error.

<html>
<body>
    <button onclick="Chat1()">Submit</button>
    <script type='text/javascript' src='file:///android_asset/www/sf.min.js'></script>
    <script type='text/javascript'>
        function Chat1() {
            var initESW = function (gslbBaseURL) {
                embedded_svc.settings.displayHelpButton = true; //Or false
                embedded_svc.settings.language = ''; //For example, enter 'en' or 'en-US'
                embedded_svc.settings.enabledFeatures = ['LiveAgent'];
                embedded_svc.settings.entryFeature = 'LiveAgent';
                embedded_svc.init(
                    'https://ulr.my.salesforce.com',
                    'https://ulr.force.com/visualforce',
                    gslbBaseURL,
                    '00D7a00000055uj',
                    'US_Universities',
                    {
                        'baseLiveAgentContentURL': 'https://c.la3-c1cs-cdg.salesforceliveagent.com/content',
                        'deploymentId': '720008Oqg',
                        'buttonId': '5730PID',
                        'baseLiveAgentURL': 'https://d.la3-c1cs-cdg.salesforceliveagent.com/chat',
                        'eswLiveAgentDevName': 'EmbeddedServiceLiveAgent_Parent0000000jLUAQ_17d9a605e8e',
                        'isOfflineSupportEnabled': false
                    }
                );
            };
            if (!window.embedded_svc) {
                var s = document.createElement('script');
                console.log("Control here1")
                var sdxMin = 'https://ulr.salesforce.com/embeddedservice/5.0/esw.min.js/'
                console.log("Control here2")
                s.src = sdxMin;
                console.log("Control here3")
                s.onload = function () {
                    initESW(null);
                }
                document.body.appendChild(s);
            }
            else {
                initESW('https://service.force.com');
            }
        }
    </script>
</body>
</html>

doc.microsoft webview, this I have followed for development. How can I fix this error ?

Edit 1 : Screenshot of Assets folder

enter image description here

R15
  • 13,982
  • 14
  • 97
  • 173

1 Answers1

0

From my perspective,you haven't put the sf.min.js file under Assets/www/sf.min.js folder.When compiling the TestWebpage.html, the system can't detect the js file as a result of the error "[AndroidProtocolHandler] Unable to open asset URL: file:///android_asset/www/sf.min.js".

enter image description here

Alexandar May - MSFT
  • 6,536
  • 1
  • 8
  • 15
  • Hi, I have kept in same folder. please check my Edit1 question I added screenshot. `TestWebpage.html` is in `Assets` and `sf.mim.js` in `Assets/www `, I am using `xamarin forms`, have you tried creating sample project with same code – R15 Mar 16 '22 at 06:57
  • Hi there, I‘ve tested it on my side and the issue appears if can't find the js file.If possible,would you mind sharing us a baisc, minimal project to test ? You can upload it to github and attach the link here . – Alexandar May - MSFT Mar 16 '22 at 07:24
  • You can exclude the sensitive information for the project and just provide a baisc, minimal project via github link?Thanks in advance! – Alexandar May - MSFT Mar 16 '22 at 07:25