首页 > 解决方案 > Xamarin Intent 空指针

问题描述

您好我正在尝试在 Xamarin 上制作一个 html 文件。制作文件后,我尝试有意打开它,但我不断得到一个空指针(Java.Lang.NullPointerException)。

是因为意图不同吗?我尝试在 invoicePage.xaml.cs 中实现意图,但每当我调用 StartActivity(intent) 时,我都会收到格式错误。

我的代码如下:

invoicePage.xaml.cs

using Android.App;
using Android.Content;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace AIFieldService.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class InvoicePage : ContentPage
    {
        public InvoicePage()
        {
            InitializeComponent();

            var htmlSource = new HtmlWebViewSource();
            htmlSource.Html =
              @"<html>
                <body>
                    <h1>Xamarin.Forms</h1>
                    <p>Welcome to WebView.</p>
                </body>
            </html>";
            web.Source = htmlSource;
        }

        public async void OnCancelClicked(Object sender, EventArgs e)
        {
            await Navigation.PopAsync();
        }

        public void OnPrintClicked(Object sender, EventArgs e)
        {
           htmlMaker hm = new htmlMaker(web.Source.ToString());
           hm.write();
        }
    }
}

htmlMaker.cs

using Android.App;
using Android.Content;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace AIFieldService
{
    [Activity(Label = "LaunchFileActivity")]
    public class htmlMaker : Activity
    {
        public string html = "";

        public htmlMaker()
        {
            html = "";
        }

        public htmlMaker(string h)
        {
            html = h;
        }


        public void write()
        {


            //This gets the full path for the "files" directory of your app, where you have permission to read/write.
            var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);

            //This creates the full file path to file
            string filePath = System.IO.Path.Combine(documentsPath, "invoice.html");

            //Check if file is there
            if (!File.Exists(filePath))
            {
                //Now create the file.
                var create = new FileStream(filePath, FileMode.Create);


                create.Dispose();
            }


            //writes to file
            File.WriteAllText(filePath, html);


            //opens file
            Android.Net.Uri uri = Android.Net.Uri.Parse(filePath);
            Intent intent = new Intent(Intent.ActionView, uri);

            //error------------------------------------
            this.StartActivity(intent);
        }
    }
}

标签: c#xamarinxamarin.forms

解决方案


您将希望将表单代码与 Android 代码分开,是的,您面临的问题的一个方面可能是因为htmlMakerAndroid 操作系统未正确创建活动。永远不要使用new MyActivity()实例化活动类,因为操作系统不会调用OnCreate, etc 方法。

我建议使用依赖服务消息中心从 Forms 共享代码中调用 Android 项目代码,这样您就可以运行 Android 特定代码来编写文件并打开浏览器。我将使用消息中心,因为它更简单。所以从你的OnPrintClicked处理程序开始:

public void OnPrintClicked(Object sender, EventArgs e)
{
   MessagingCenter.Send<InvoicePage, string>(this, "html", web.Source.ToString());
}

然后在MainActivity.OnCreateAndroid项目的方法中,添加以下内容:

Xamarin.Forms.MessagingCenter.Subscribe<InvoicePage, string>(this, "html", (sender, html) => 
    {
        //I changed this path to be a public path so external apps can access the file. 
        //Otherwise you would have to grant Chrome access to your private app files
        var documentsPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments).AbsolutePath;
        Directory.CreateDirectory(documentsPath);

        //This creates the full file path to file
        string filePath = System.IO.Path.Combine(documentsPath, "invoice.html");

        //writes to file (no need to create it first as the below will create if necessary)
        File.WriteAllText(filePath, html);

        //opens file
        Android.Net.Uri uri = Android.Net.Uri.FromFile(new Java.IO.File(filePath));

        Intent intent = new Intent(Intent.ActionView, uri);
        intent.AddFlags(ActivityFlags.NewTask);
        intent.SetClassName("com.android.chrome", "com.google.android.apps.chrome.Main");

        this.StartActivity(intent);
    });

推荐阅读