'Xamarin Android: System.IO.DirectoryNotFoundException: Could not find a part of the path
I have a Xamarin.Forms Android app where the page in question looks like this:
<Grid>
<ScrollView>
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Image x:Name="CapturedImage" Source="{Binding Capture}" HeightRequest="100" WidthRequest="100"/>
<Button Margin="0,10,0,0" Text="Capture photo"
Command="{Binding OpenCameraCommand}"
BackgroundColor="{StaticResource Primary}"
TextColor="White" />
<Label Text="{Binding Description}" />
</StackLayout>
</ScrollView>
</Grid>
With the button I open the Android native camera, which works. In the ViewModel the following happens:
public class CaptureViewModel : BaseViewModel
{
private string _description;
public string Description
{
get => _description;
set
{
_description = value;
OnPropertyChanged();
}
}
private ImageSource _capture;
public ImageSource Capture
{
get => _capture;
set
{
_capture = value;
Description = value.ToString();
OnPropertyChanged();
}
}
public ICommand OpenCameraCommand { get; }
public CaptureViewModel()
{
Title = "Capture";
OpenCameraCommand = new Command(OnExecute);
}
private async void OnExecute()
{
await TakePhotoAsync();
}
private async Task TakePhotoAsync()
{
var mpo = new MediaPickerOptions
{
Title = "test"
};
var photo = await MediaPicker.CapturePhotoAsync(mpo);
await LoadPhotoAsync(photo);
var image = await Image.FromFileAsync(Capture.ToString());
var client = await ImageAnnotatorClient.CreateAsync();
var textAnnotations = await client.DetectTextAsync(image);
foreach (var text in textAnnotations)
{
Description = text.Description;
}
}
private async Task LoadPhotoAsync(FileResult photo)
{
if (photo == null)
{
Capture = null;
return;
}
var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var newFile = Path.Combine(path, photo.FileName);
using (var stream = await photo.OpenReadAsync())
{
var newStream = File.OpenWrite(newFile);
await stream.CopyToAsync(newStream);
newStream.Close();
newStream.Dispose();
}
Capture = newFile;
}
}
I actually want to use the ImageAnnotator seen in the VM, but I always get an error when trying to getting the captured image for processing.
System.IO.DirectoryNotFoundException: 'Could not find a part of the path "/File: /data/user/0/com.companyname.app2/files/df033720bb9646928a9626e25e116990.jpg".'
My permissions in AndroidManifest.xml look like:
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<application android:label="App2.Android" android:theme="@style/MainTheme"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
I don't know what else could be wrong, but I tried a few other things, that didn't help. What might be the problem?
EDIT: I can see the Capture in the view, btw. and the Label for debugging reasons also shows a path (the same as in the pic).
Solution 1:[1]
So the solution here was to use the FullPathproperty from the returned FileResult to get the correct path needed to turn it into a stream.
wrong:
var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var newFile = Path.Combine(path, photo.FileName);
right:
var photo = await MediaPicker.CapturePhotoAsync(mpo);
var photoFullPath = photo.FullPath;
Capture = photoFullPath;
var image = await Image.FromFileAsync(photoFullPath);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | hansoolow |
