Je passe actuellement par le processus d'apprentissage de Xamarin.Forms. J'essaie actuellement d'implémenter des fonctions de caméra à l'aide de la bibliothèque Plugin.Media.CrossMedia.
Mis en œuvre ci-dessous:
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;
}
}
Cependant, lors de l'exécution de la méthode "TakePhotoAsync", je reçois l'erreur suivante.
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.
J'ai essayé de chercher cela, mais en vain. Mon fichier AndroidManifest.xml ressemble à ceci en ce 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>
Mon idée est que je dois déclarer quelque chose ici, mais je n'ai pas pu trouver quoi, et tous les tutoriels que j'ai suivis ne passent par rien avec la configuration d'un fournisseur de fichiers.
Aucune suggestion?
Le readme dit:
Si votre application cible Android N (API 24) ou plus récent, vous devez utiliser la version 2.6.0+.
Vous devez également ajouter quelques fichiers de configuration supplémentaires pour adhérer au nouveau mode strict:
1.) Ajoutez ce qui suit à votre AndroidManifest.xml à l'intérieur des balises:
<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 doit être défini sur le nom de votre package d'application!
2.) Ajoutez un nouveau dossier appelé xml dans votre dossier Resources et ajoutez un nouveau fichier XML appelé file_paths.xml
Ajoutez le code suivant:
<?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 doit être défini sur le nom de votre package d'application!
Vous pouvez en savoir plus sur: https://developer.Android.com/training/camera/photobasics.html
Dans mon cas, c'est parce que j'avais placé FileProvider au mauvais endroit dans le fichier AndroidManifest.xml. Il devait être à l'intérieur des balises <Application>.
<?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>
Le problème que j'avais était lié à la sensibilité à la casse.
Sur la ligne ci-dessous
<provider Android:name="Android.support.v4.content.FileProvider"
Android:authorities="com.myexample.myapp.fileProvider"
Android:exported="false"
Android:grantUriPermissions="true">
J'ai eu par erreur une seule lettre majuscule sur la ligne Android:authorities="com.myexample.myapp.fileProvider"
. Ça devrait être:
Android:authorities="com.myexample.myapp.fileprovider" <!-- all lowercase -->
Ou
Android:authorities="${applicationId}.fileprovider"
Le nom et la valeur du package pour Android:authorities
doit être en minuscules. Sinon, vous obtiendrez l'erreur:
System.ArgumentException: impossible d'obtenir l'emplacement du fichier. Cela signifie très probablement que les informations du fournisseur de fichiers ne sont pas définies dans votre fichier Android Manifest. Veuillez consulter la documentation sur la façon de configurer cela dans votre projet.
Avec la dernière version, la configuration XML correcte est (sans ajouter le nom du package au chemin d'accès)
<?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>
Si vous définissez un chemin combinant nom du package comme ci-dessous
<external-path name="my_images" path="Android/data/YOUR_APP_PACKAGE_NAME/files/Pictures" />
Cela peut donner ce type d'erreur.