我一直在尝试生成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)
上的行。