19

I am currently going through the process of Learning Xamarin.Forms. I am currently attempting to implement Camera functions using the Plugin.Media.CrossMedia library.

Implemented below:

public async Task<ImageSource> StartCamera()
{
    await CrossMedia.Current.Initialize();


    if (Plugin.Media.CrossMedia.Current.IsTakePhotoSupported && CrossMedia.Current.IsCameraAvailable)
    {
            var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions() { SaveToAlbum=false, SaveMetaData=false});

            if (photo != null)
                return ImageSource.FromStream(() => { return photo.GetStream(); });
            else
                return null;



    }
    else
    {
        return null;
    }
}

However upon executing the 'TakePhotoAsync' method I recieve the following error.

System.ArgumentException: Unable to get file location. This most likely means that the file provider information is not set in your Android Manifest file. Please check documentation on how to set this up in your project.

I have tried looking this up but to no avail. My AndroidManifest.xml file looks like this at the moment.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="RCPTTracker.Android" android:versionCode="1" android:versionName="1.0">
    <uses-sdk />
    <application android:label="RCPTTracker.Android"></application>
</manifest>

My inkling is that I need to declare something in here, but I haven't been able to find what, and all tutorials i have followed don't go through anything with setting up a File Provider.

Any suggestions?

Duncan Palmer
  • 2,865
  • 11
  • 63
  • 91

10 Answers10

23

The readme says:

If your application targets Android N (API 24) or newer, you must use version 2.6.0+.

You must also add a few additional configuration files to adhere to the new strict mode:

1.) Add the following to your AndroidManifest.xml inside the tags:

<provider android:name="android.support.v4.content.FileProvider" 
                android:authorities="YOUR_APP_PACKAGE_NAME.fileprovider" 
                android:exported="false" 
                android:grantUriPermissions="true">
                <meta-data android:name="android.support.FILE_PROVIDER_PATHS" 
                android:resource="@xml/file_paths"></meta-data>
</provider>

YOUR_APP_PACKAGE_NAME must be set to your app package name!

2.) Add a new folder called xml into your Resources folder and add a new XML file called file_paths.xml

Add the following code:

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

YOUR_APP_PACKAGE_NAME must be set to your app package name!

You can read more at: https://developer.android.com/training/camera/photobasics.html

Marco
  • 254
  • 2
  • 6
  • 1
    Thank you. So I had followed tutorials which said the exact same thing, except in android:authorities they had 'YOUR_PACKAGE_NAME.provider'. changed to 'MY_PACKAGE_NAME.fileprovider' and it worked :) – Duncan Palmer Jan 25 '18 at 02:39
  • I am having a hard time with this. I changed mine to `android:authorities="com.Igs.Mobile.TBOSS.fileprovider"` Is that what you mean, or should it literally be `MY_PACKAGE_NAME.fileprovider` – JonathanPeel Jan 29 '18 at 08:10
  • @JonathanPeel not literally. If you go into the Android Manifest Options window, it'll be what is in the package name input box with '.fileprovider' added to the end. – Duncan Palmer Jan 30 '18 at 21:09
  • 1
    I am really not getting this right. I have gone through the readme about 10 times, double checking every line, and I still get this error. Any ideas on things I can try? – JonathanPeel Mar 15 '18 at 06:22
  • I hadn't configured the package name! That was my mistake. Thank you – Alejandro Bastidas Nov 14 '18 at 01:16
  • 3
    @JonathanPeel Instead of android:authorities="YOUR_APP_PACKAGE_NAME.fileprovider" ,we can also use android:authorities="${applicationId}.fileprovider" – Himen Suthar May 22 '19 at 18:44
  • I tried everything in this answer and in addition to that. setting android:authorities="${applicationId}.fileprovider" worked – U.P Sep 01 '20 at 11:45
11

In my case it was because I had put the FileProvider in the wrong place in the AndroidManifest.xml file. It needed to be inside the <Application> tags.

    <?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.myapp.app1" android:installLocation="auto">
        <uses-sdk android:minSdkVersion="22" android:targetSdkVersion="27" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.BROADCAST_WAP_PUSH" />
        <uses-permission android:name="android.permission.CAMERA" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_SETTINGS" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
        <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
        <application android:label="app1.Android">
            <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyCZF1O9_7-MXlxYfAEIxBQkr-dR8RiwiYE" />

            <!-- ADD FILE PROVIDER HERE -->
            <provider android:name="android.support.v4.content.FileProvider"
                  android:authorities="com.myapp.app1.fileprovider"
                  android:exported="false"
                  android:grantUriPermissions="true">
              <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
              android:resource="@xml/file_paths"></meta-data>
            </provider>

        </application>
    </manifest>
Noobie3001
  • 1,230
  • 18
  • 31
6

The problem I had was related to case-sensitivity.

On the line below

<provider android:name="android.support.v4.content.FileProvider"
          android:authorities="com.myexample.myapp.fileProvider"
          android:exported="false"
          android:grantUriPermissions="true">

I erroneously had a single uppercase letter on the line android:authorities="com.myexample.myapp.fileProvider". It should be:

android:authorities="com.myexample.myapp.fileprovider"  <!-- all lowercase -->

Or

android:authorities="${applicationId}.fileprovider"    

The package name and value for android:authorities should be lowercase. Otherwise you will get the error:

System.ArgumentException: Unable to get file location. This most likely means that the file provider information is not set in your Android Manifest file. Please check documentation on how to set this up in your project.

haldo
  • 14,512
  • 5
  • 46
  • 52
5

Make sure you only have one set of <application> tags

I was stuck on this error for literally weeks... Then I realised I had duplicate application tags.

defined once like this: <application android:label="App2.Android"></application>

the second set of <application> tags had the correct configuration lower down, but were being ignored. Removing the empty tags solved the issue for me.

Oscar Chambers
  • 899
  • 9
  • 25
  • 1
    This is what killed me. Thanks for highlighting this as there was no warning or anything about the duplication – Joseph Devlin Apr 13 '20 at 11:50
  • Same, by default it should have one, although its only one line. No need to make your own. I'll post on the github asking them to clarify this in the readme. – pseudoabdul Oct 09 '20 at 01:23
3

Marco's solution is almost right. For it to work in my project I had to change

android:authorities="YOUR_APP_PACKAGE_NAME.fileprovider"
to
android:authorities="${applicationId}.fileprovider" 

in the AndroidManifest.xml file.

Arun J
  • 687
  • 4
  • 14
  • 27
Ren-Heok
  • 67
  • 1
  • 1
  • 11
1

Above answers resolved this issue for me. Here's what my AndroidManifest.xml looks like (using ${applicationId} for the authorities tag helps because sometimes you just don't know exactly how your app name is):

<?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.app2">

<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application android:label="App2.Android" android:theme="@style/MainTheme">
    <provider android:name="androidx.core.content.FileProvider" 
          android:authorities="${applicationId}.fileprovider" 
          android:exported="false" 
          android:grantUriPermissions="true">
          <meta-data android:name="android.support.FILE_PROVIDER_PATHS" 
          android:resource="@xml/file_paths"></meta-data>
    </provider>
</application>

</manifest>
Plan Man
  • 23
  • 1
  • 8
1
<provider android:name="androidx.core.content.FileProvider"
      android:authorities="APP_PACKAGE_NAME.fileprovider"
      android:exported="false"
      android:grantUriPermissions="true">

  <meta-data
         android:name="android.support.FILE_PROVIDER_PATHS"
         android:resource="@xml/file_paths"></meta-data>
</provider>

Xml must be in under xml folder

enter image description here

karayakar
  • 19
  • 3
0

With the latest version, correct XML configuration is (without adding the package name to the path)

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

If you set path combining the package name like below

<external-path name="my_images" path="Android/data/YOUR_APP_PACKAGE_NAME/files/Pictures" />

It may give this type of error.

dush88c
  • 1,918
  • 1
  • 27
  • 34
0

Android Support Libraries are now in the androidx.* package hierarchy instead of android.support.

So use following provider tag in you application's manifest.xml file.

<provider android:name="androidx.core.content.FileProvider" 
            android:authorities="YOUR_APP_PACKAGE_NAME.fileprovider" 
            android:exported="false" 
            android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" 
            android:resource="@xml/file_paths"></meta-data></provider>

It must be under application tag.

0

In addition to these things I had to do one more thing to get rid of this error. I had manually added the xml folder and file_paths.xml into the project folder. However, I had not yet added them to the project in the solution. Once I right clicked on the Resources folder and added New Folder (xml) and Existing Item (file_paths.xml) the error went away.

charles young
  • 2,269
  • 2
  • 23
  • 38