【问题标题】:Xamarin HybridWebView navigate to page in cache folderXamarin HybridWebView 导航到缓存文件夹中的页面
【发布时间】:2020-07-25 20:53:19
【问题描述】:

我想制作一个 xamarin 表单 webview 应用程序,该应用程序下载网页(应用程序本身)然后显示它。在下载之前,我会显示一个本地登录页面,一旦用户提交表单,它将调用该应用程序。本地页面将在应用程序包内,下载的页面将下载到应用程序可以存储数据的位置(此 uwp 示例中的 CommenApplicationData,但我必须使用 iOS 上的文档文件夹)。

我已经制作了一个 .NET Core 库,可以下载、解包并支持 webview 中的网页使用的脚本命令。该库的主要入口类称为:BroadsheetInterface,它接受来自 webview (BroadsheetInterface.RunCommand) 的消息,并使用接口对 webview(RunJavascript) 进行回调。

为了显示本地“登录页面”和下载的“应用程序页面”或“启动器页面”,我使用了 Xamarin 的 HybridWebView 示例。然后我修改了平台特定的 hybridwebview 来做它自己的导航,如下所示:

// IWebView is a interface that is used for the BroadsheetInterface can do callbacks 
// to this control
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Windows.UI.Xaml.Controls.WebView>, IWebView 
{
    // The pointer to the current "BroadsheetInterface", a class that has all logic of 
    // the webpage inside the webview
    public BroadsheetInterface_Helper BroadsheetInterface { get; set; }

    // The standard call to setup the webview to a local page, I use this call to show 
    // the login page.
    protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            SetNativeControl(new Windows.UI.Xaml.Controls.WebView());
        }
        if (e.OldElement != null)
        {
            Control.NavigationCompleted -= OnWebViewNavigationCompleted;
            Control.ScriptNotify -= OnWebViewScriptNotify;
        }
        if (e.NewElement != null)
        {
            Control.NavigationCompleted += OnWebViewNavigationCompleted;
            Control.ScriptNotify += OnWebViewScriptNotify;

            LoadLoginPage();                
        }
    }

    // Once the local page has been loaded I setup the library (note the "this" 
    // parameter), then check if the user has checked the "remember login" checkbox 
    // last time he or she logged in.
    void OnWebViewNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
    {
        if (args.IsSuccess)
        {
            BroadsheetInterface = new BroadsheetInterface_Helper(this);
            BroadsheetInterface.Browser_SetLogin();
        }
    }

    // If the Javascript inside the webview calls the app, the command will be passed 
    // into the BroadsheetInterface to be processed. 
    void OnWebViewScriptNotify(object sender, NotifyEventArgs e)
    {
        BroadsheetInterface.RunCommand(e.Value);
    }

    // If the library want to call the webpage inside the webview, it will call 
    // this function
    public async void RunJavascript(string script)
    {
        await Control.InvokeScriptAsync("eval", new[] { script });
    }

    // Show the login page
    public void LoadLoginPage()
    {
        Control.Source = new Uri(string.Format("ms-appx-web:///Content//{0}", Element.Uri));
    }

    // Show the launcher page
    public void LoadLauncherPage()
    {
        // The location of the launcher page
        var fullname = BroadsheetInterface.AccountHelper.CurrentAccount.GetLauncherPage().FullName;
        // fullname = "C:\Users\wille\AppData\Local\Packages\a05728a3-841f-4ef2-8f13-f1dbf39590a0_tbz3402trp7yy\LocalState\ProgramData\Launcher\willem\index.html"

        // Convert the path to a url
        var url = "file:///" + fullname.Replace("\\", "/");
        // url = "file:///C:/Users/wille/AppData/Local/Packages/a05728a3-841f-4ef2-8f13-f1dbf39590a0_tbz3402trp7yy/LocalState/ProgramData/Launcher/willem/index.html"

        // Set it to the webview
        Control.Source = new Uri(url);
        // DOESN'T WORK :(
    }

    // This is called from the library to get the location where to store 
    // the launcher page
    public string GetCacheFolder()
    {
        return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
    }
}

现在应用程序运行,我可以登录,当我提交时,它开始下载文件。下载文件后,我想设置 webview 以显示已下载的启动器页面。所以我调用了“LoadLauncherPage()”函数,但它不会更改为下载的页面。这就像设置“Source”参数没有任何作用。

【问题讨论】:

    标签: c# xamarin.forms uwp


    【解决方案1】:

    好的,我自己发现了。

    我猜不允许将 WebView 的 Source 属性设置为“file:///”url。所以我遇到了这个解决方案:

    // Show the launcher page
    public void LoadLauncherPage()
    {
        Uri uri = Control.BuildLocalStreamUri("Launcher", "/index.html");
        Control.NavigateToLocalStreamUri(uri, new StreamResolver(BroadsheetInterface));
    }
    
    // Resolver for mapping the files
    public class StreamResolver : IUriToStreamResolver
    {
        private BroadsheetInterface_Helper broadsheetInterface;
    
        public StreamResolver(BroadsheetInterface_Helper broadsheetInterface)
        {
            this.broadsheetInterface = broadsheetInterface;
        }
    
        public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
        {
            if (uri == null) throw new Exception();
            return GetContent(uri.AbsolutePath).AsAsyncOperation();
        }
        private async Task<IInputStream> GetContent(string path)
        {
            try
            {
                string fullname = broadsheetInterface.AccountHelper.CurrentAccount.RootFolder.FullName + path.Replace("/", "\\");
                StorageFile f = await StorageFile.GetFileFromPathAsync(fullname);
                IRandomAccessStream stream = await f.OpenAsync(FileAccessMode.Read);
                return stream;
            }
            catch (Exception) { throw new Exception("Invalid path"); }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-18
      • 2016-07-20
      • 1970-01-01
      • 2019-01-03
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多