Xamarin.Forms Android FileProvider:尝试读取文件时出现Java.Lang.NullPointerException

时间:2018-11-11 13:48:26

标签: android xamarin android-intent android-fileprovider

我一直在尝试生成Word文件,并使用Xamarin.Forms在Android上打开它。我可以创建文件,但是在尝试读取时会引发以下错误:

Java.Lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference

我正在使用的代码如下:

AndroidManifest.xml包含:

<application>
    <provider android:name="android.support.v4.content.FileProvider" 
            android:authorities="com.ESFJP.ESFAtas.fileprovider" 
            android:grantUriPermissions="true"
            android:exported="false">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/>
    </provider>
</application>

位于Resources / xml文件夹中的provider_paths.xml是:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <external-path name="external_files" path="/Atas"/>
  <files-path name="files" path="/Atas"/>
</paths>

保存文件并打开的异步方法:

public async Task Save(string fileName, string contentType, MemoryStream stream)
{

    string exception = string.Empty;
    string root = null;
    if (Android.OS.Environment.IsExternalStorageEmulated)
    {
        root = Android.OS.Environment.ExternalStorageDirectory.ToString();
    }
    else
        root = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

    Java.IO.File myDir = new Java.IO.File(root + "/Atas");
    myDir.Mkdir();
    Java.IO.File file = new Java.IO.File(myDir, fileName);

    if (file.Exists()) file.Delete();


    try
    {
        //The permission failure happens in this line when the target version is set to API Level 27 Nougat
        FileOutputStream outs = new FileOutputStream(file);
        stream.Position = 0;
        outs.Write(stream.ToArray());
        outs.Flush();
        outs.Close();
    }

    catch (Exception e)
    {
        //The permission failure can be seen here if the target version is set to API level 27 Nougat
        exception = e.ToString();
    }
    finally
    {
        stream.Dispose();
    }

    if (file.Exists())
    {
        string auth = "com.ESFJP.ESFAtas.fileprovider";
        string extension = Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(Uri.FromFile(file).ToString());
        string mimeType = Android.Webkit.MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
        if (mimeType == null)
            mimeType = "*/*";

        //The Java.Lang.NullPointerException is thrown from this line \/\/\/
        Uri uri = FileProvider.GetUriForFile(Forms.Context, auth, file);

        Intent intent = new Intent(Intent.ActionView);
        intent.SetDataAndType(uri, mimeType);
        intent.AddFlags(ActivityFlags.GrantReadUriPermission | ActivityFlags.GrantWriteUriPermission);
        intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.NoHistory);

        var resInfoList = Forms.Context.PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
        foreach (var resolveInfo in resInfoList)
        {
            var packageName = resolveInfo.ActivityInfo.PackageName;
            Forms.Context.GrantUriPermission(packageName, uri, ActivityFlags.GrantWriteUriPermission | ActivityFlags.GrantPrefixUriPermission | ActivityFlags.GrantReadUriPermission);
        }

        Forms.Context.StartActivity(intent);
    }

}

我一直在努力处理这段代码。许多线程告诉了这个问题在provider_paths.xml上,但是我不知道原因,位置或什至是实际存在。

编辑。:为了更清楚地重现问题,我将示例上传到了我的GitHub:https://github.com/RaelsonCraftz/XamarinFileProviderSample

还有一个小更新。如果将Targed Android version设置为Use Compile using SDK version,则应用程序至少会创建文件,但无法打开,并给出上述Java.Lang.NullPointerException。如果将其设置为Android 8.1(API级别27-Oreo),它将无法创建文件。它说尚未在此行exception = e.ToString();上授予该许可。我已将发生这种情况的行标记为public async Task Save(string fileName, string contentType, MemoryStream stream)上的行。

0 个答案:

没有答案