Xamarin.Forms Android FileProvider: Java.Lang.NullPointerException when trying to read file

I've been trying generate word files and open it on an Android using Xamarin.Forms. I can create the file, but the following error is thrown when I try to read:

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

The code I'm using is as follows:

The AndroidManifest.xml contains:

<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>

The provider_paths.xml, which lies in the folder Resources/xml, is:

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

The async method to save the file and open:

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);
    }
}

I've been struggling with this code. Many threads told about the issue being on the provider_paths.xml, but I can't figure out why or where or even if it's actually there.

Also, a small note. If you set the Targed Android version to Use Compile using SDK version the app manages to at least create the file, but it won't open, giving the Java.Lang.NullPointerException mentioned above. IF you set it to Android 8.1 (API Level 27 - Oreo), it won't manage to create the file. It says that the permission has not been granted at this line exception = e.ToString();. I've marked the line where that happens, it's on the public async Task Save(string fileName, string contentType, MemoryStream stream).

I created a sample in my GitHub where this issue happens: https://github.com/RaelsonCraftz/XamarinFileProviderSample. Any help is appreciated!

Answers

  • DeepakDYDeepakDY INMember ✭✭✭

    Hello @RaelsonCraftz ,

    you got any solution.

    i am facing the same problem

  • RaelsonCraftzRaelsonCraftz BRMember ✭✭

    Yes, I did! Apparently there were a few issues on the code. To start:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1"        android:versionName="1.0" package="com.companyname.FileProviderSample" android:installLocation="preferExternal">
        <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
        <application android:label="FileProviderSample.Android"></application> <!--THIS LINE MUST BE REMOVED-->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <application>
            <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.companyname.FileProviderSample.fileprovider" android:grantUriPermissions="true" android:exported="false">
                <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
            </provider>
        </application>
    </manifest>
    

    Having two application tags apparently was one of the issues. Apparently this was the killing one. There were a few other modifications that the guys from Syncfusion suggested to fix my implementation of their component (DocIO), but I think that the core issue was this. There's more on this reference: https://www.syncfusion.com/forums/138871/error-when-saving-document-with-dependency-service

Sign In or Register to comment.