未设置 Xamarin Forms 文件提供程序

Xamarin Forms File Provider not set

我目前正在学习 Xamarin.Forms。我目前正在尝试使用 Plugin.Media.CrossMedia 库来实现相机功能。

执行如下:

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

然而,在执行 'TakePhotoAsync' 方法时,我收到以下错误。

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.

我曾尝试查找此内容,但无济于事。我的 AndroidManifest.xml 文件目前看起来像这样。

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

我的想法是我需要在这里声明一些东西,但我一直无法找到什么,而且我遵循的所有教程都没有通过设置文件提供程序来完成任何事情。

有什么建议吗?

自述文件说:

如果您的应用程序面向 Android N (API 24) 或更高版本,则必须使用 2.6.0+ 版本。

您还必须添加一些额外的配置文件以遵守新的严格模式:

1.) 将以下内容添加到您的 AndroidManifest.xml 标签内:

<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必须设置为您的应用程序包名称!

2.) 在资源文件夹中添加一个名为 xml 的新文件夹,并添加一个名为 file_paths.xml

的新 XML 文件

添加以下代码:

<?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必须设置为您的应用程序包名称!

您可以在以下位置阅读更多信息:https://developer.android.com/training/camera/photobasics.html

在我的例子中,这是因为我将 FileProvider 放在 AndroidManifest.xml 文件中的错误位置。它需要在 标签内。

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

我遇到的问题与区分大小写有关。

下一行

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

我错误地在行 android:authorities="com.myexample.myapp.fileProvider" 上输入了一个大写字母。应该是:

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

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

android:authorities 的包名和值应该是小写的。否则你会得到错误:

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.

使用最新版本,正确的XML配置是(不在路径中添加包名)

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

如果你设置路径结合包名如下

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

可能会出现此类错误。

Marco 的解决方案几乎是正确的。为了让它在我的项目中工作,我必须更改

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

AndroidManifest.xml 文件中。

确保您只有一组 标签

我被这个错误困扰了好几个星期...然后我意识到我有重复的应用程序标签。

像这样定义一次: <application android:label="App2.Android"></application>

第二组 标签的配置正确,但被忽略了。删除空标签解决了我的问题。

Android 支持库现在位于 androidx.* 包层次结构中,而不是 android.support.

因此,请在您应用程序的 manifest.xml 文件中使用以下提供商标签。

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

必须在应用程序标签下。

以上回答为我解决了这个问题。这是我的 AndroidManifest.xml 的样子(使用 ${applicationId} 作为 authorities 标签会有所帮助,因为有时您只是不知道您的应用名称到底是什么):

<?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>
<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 必须在 xml 文件夹下

除了这些之外,我还必须做一件事来消除这个错误。我已将 xml 文件夹和 file_paths.xml 手动添加到项目文件夹中。但是,我还没有将它们添加到解决方案中的项目中。一旦我右键单击资源文件夹并添加新文件夹 (xml) 和现有项目 (file_paths.xml),错误就消失了。