1

I am trying to implement a file provider in Xamarin.Forms, and I am having an issue loading my file paths file. Whenever I attempt to build that app, I get the following error:

No resource found that matches the given name (at 'resource' with value '@xml/file_paths')

The file_paths.xml file is located in the resources directory under the xml folder. Any help would greatly appreciated. Here are my relevant files:

Android Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" package="com.mycompany.myapp" android:versionName="1" android:installLocation="internalOnly">
<uses-sdk android:targetSdkVersion="26" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:icon="@drawable/advanced" android:label="FD CANNECT" android:windowSoftInputMode="adjustPan" android:descendantFocusability="afterDescendants" >
    <provider 
      android:name="android.support.v4.content.FileProvider" 
      android:authorities="com.myapp.fileprovider" 
      android:exported="false" 
      android:grantUriPermissions="true">
        <meta-data 
          android:name="android.support.FILE_PROVIDER_PATHS" 
          android:resource="@xml/file_paths" />
    </provider>
</application>
</manifest>

file_paths.xml

<?xml version="1.0" encoding="utf-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="downloads" path="downloads/" />
</paths>

MainActivity.cs

using Android.Provider;
using Android.Support.V4.Content;
using CAN2LAN.Droid;
using Java.Lang;

[assembly: Xamarin.Forms.Dependency(typeof(ShareIntent))]

namespace CAN2LAN.Droid
{
using Acr.UserDialogs;
using System.Linq;
using Xamarin.Forms;

using Xamarin.Forms.Platform.Android;

global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        UserDialogs.Init(this);
        base.OnCreate(bundle);
        global::Xamarin.Forms.Forms.Init(this, bundle);

        Downloaded();

        Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) => {
            args.Handled = false;
        };

        this.LoadApplication(new App());
    }

    public void Downloaded() {
        CrossDownloadManager.Current.PathNameForDownloadedFile = new System.Func<IDownloadFile, string>(file => {
            string fileName = Android.Net.Uri.Parse(file.Url).Path.Split('/').Last();
            return System.IO.Path.Combine(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDownloads).AbsolutePath, fileName);
        });
    }


}

public class ShareIntent : IShareable {
    public void OpenShareIntent(string fileName) {         
        OpenFile(fileName);
    }

    public void OpenFile(string fileName) {
        string auth = "com.myapp.fileprovider";
        System.Diagnostics.Debug.WriteLine("Auth is " + auth);
        string mimeType = Android.Webkit.MimeTypeMap.Singleton.GetMimeTypeFromExtension(Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(fileName.ToLower()));
        if (mimeType == null)
            mimeType = "*/*";
        Android.Net.Uri uri = null;
        System.Diagnostics.Debug.WriteLine("Created authentication and mime type");
        var file = new Java.IO.File(System.IO.Path.Combine(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryDownloads).AbsolutePath, fileName));
        System.Diagnostics.Debug.WriteLine("File size is " + file.TotalSpace);
        System.Diagnostics.Debug.WriteLine("Froms context is " + Forms.Context);
        try {
             uri = FileProvider.GetUriForFile(Forms.Context, auth, file);
        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine("Exception " + e);
        }

        System.Diagnostics.Debug.WriteLine("URI is "  + uri);


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

        System.Diagnostics.Debug.WriteLine("Intent is created");
        // Trying to allow writing to the external app ...
        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);
        }
        System.Diagnostics.Debug.WriteLine("We have created res info lsit");
        try
        {
            System.Diagnostics.Debug.WriteLine("We are about to show the intent");
            Forms.Context.StartActivity(intent);
            System.Diagnostics.Debug.WriteLine("We ahe shwoed the intent");

        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine("We have caugth an exception " + e);
        }


    }
}
}

3 Answers3

2

I haven't tried but this could be the issue. Here problem seem with your file_paths.xml file. You are giving name & path both are same

name="downloads" path="downloads/"

Those might be different

Either this

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="files"
        path="external_files"/>
</paths>

Or

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

For more information you can visit this

Edit 1

Check file_paths.xml file build action, It should be AndroidResource

R15
  • 13,982
  • 14
  • 97
  • 173
  • I changed the file_paths.xml to your code and I'm still getting the same error. I've also tried restarting Visual Studio and restarting my computer. –  Jul 31 '18 at 15:29
  • Don't change according to me change according you. File name should be file name & path should be path `name="share" path="external_files` – R15 Jul 31 '18 at 15:30
  • 3
    I set the file_paths.xml as an AndroidResource, which seemed to have solved the initial error. However, no when the app launches, I get the following exception: `Java.Lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.ContentFrameLayout.setId(int)' on a null object reference` –  Jul 31 '18 at 17:24
  • 3
    Changing the build action to _AndroidResource_ worked for me. – bradykey Aug 12 '19 at 23:20
2

I believe the real answer to this question was mentioned by @bradykey

"Changing the build action to AndroidResource"

You can do this by right clicking the file and selecting properties. Here you can choose the build action.

David Andrew Thorpe
  • 838
  • 1
  • 9
  • 23
0

Make sure your XML file is all lowercase. That fixed it for me.