Android 11 Api 30 使用 Xamarin Essentials 拍照并保存到设备
Android 11 Api 30 with Xamarin Essentials Take Photo and save to device
是否可以使用 Xamarin Essentials 拍摄 Android 11 - Api 30 的照片并将其保存到设备中?我过去曾使用 Xam.Media.Plugin 来执行此操作。但我更愿意只使用 Xamarin Essentials。我目前让我的应用程序拍照,然后以编程方式将每张照片上传到 Azure(运行良好)。但是,我还想在互联网连接不佳时将照片副本保存到设备上作为备份,我的用户经常遇到这种情况。下面的代码没有捕获并显示下面的两个警报,但是没有任何内容保存到我的设备中。我的代码包含在下面:
private async void TakePhoto()
{
try
{
Console.WriteLine("Camera started");
string fN = "RI-" + Asset_ID.Text + lblUniqueName.Text + ".jpg";
var file = await MediaPicker.CapturePhotoAsync();
if (file == null)
return;
var content = new MultipartFormDataContent();
content.Add(new StreamContent(await file.OpenReadAsync()), "file", fN);
string directory = Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "/pictures";
string filePath = Path.Combine(directory, fN);
DirectoryInfo info = new DirectoryInfo(directory);
if (!info.Exists)
{
info.Create();
}
Stream fileStream = await file.OpenReadAsync();
await DisplayAlert("1", "Stream Read", "OK");
using (FileStream outputFileStream = new FileStream(filePath, FileMode.Create))
{
fileStream.CopyTo(outputFileStream);
}
await DisplayAlert("2", "Stream Saved", "OK");
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("https://tasmanoperationsportal.azurewebsites.net/UploadFile", content);
Console.WriteLine("App Returned");
await DisplayAlert("Successful", "Photo uploaded to the cloud", "OK");
}
catch
{
await DisplayAlert("Unsuccessful", "No internet connectivity, use default camera App and upload later", "OK");
}
}
Android清单
<?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.tcminspect2_0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
<application android:label="TCmInspect2_0.Android" android:theme="@style/MainTheme" android:requestLegacyExternalStorage="true" ></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
可以参考Media Picker官方文档
(https://docs.microsoft.com/en-us/xamarin/essentials/media-picker?context=xamarin%2Fandroid&tabs=android)
根据你的代码,你使用后string filePath = Path.Combine(directory, fN);
就可以使用
using (var stream = await file.OpenReadAsync())
using (var newStream = File.OpenWrite(filePath))
await stream.CopyToAsync(newStream);
PhotoPath = filePath;
PhotoPath为文件所在路径saved.Then只需要调用PhotoPath即可获取本地存储的图片
我创建了一个简单的示例供您参考(我创建了一个按钮来拍照并将其保存到设备):
cs页面代码如下:
public string PhotoPath { get; set; } = null;
public MainPage()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
var file = await MediaPicker.CapturePhotoAsync();
await LoadPhotoAsync(file);
if (file == null)
return;
async Task LoadPhotoAsync(FileResult photo)
{
// canceled
if (photo == null)
{
PhotoPath = null;
return;
}
// save the file into local storage
var newFile = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using (var stream = await photo.OpenReadAsync())
using (var newStream = File.OpenWrite(newFile))
await stream.CopyToAsync(newStream);
PhotoPath = newFile;
myImg.Source = PhotoPath;//Show on the front page
}
}
截图如下:
是否可以使用 Xamarin Essentials 拍摄 Android 11 - Api 30 的照片并将其保存到设备中?我过去曾使用 Xam.Media.Plugin 来执行此操作。但我更愿意只使用 Xamarin Essentials。我目前让我的应用程序拍照,然后以编程方式将每张照片上传到 Azure(运行良好)。但是,我还想在互联网连接不佳时将照片副本保存到设备上作为备份,我的用户经常遇到这种情况。下面的代码没有捕获并显示下面的两个警报,但是没有任何内容保存到我的设备中。我的代码包含在下面:
private async void TakePhoto()
{
try
{
Console.WriteLine("Camera started");
string fN = "RI-" + Asset_ID.Text + lblUniqueName.Text + ".jpg";
var file = await MediaPicker.CapturePhotoAsync();
if (file == null)
return;
var content = new MultipartFormDataContent();
content.Add(new StreamContent(await file.OpenReadAsync()), "file", fN);
string directory = Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "/pictures";
string filePath = Path.Combine(directory, fN);
DirectoryInfo info = new DirectoryInfo(directory);
if (!info.Exists)
{
info.Create();
}
Stream fileStream = await file.OpenReadAsync();
await DisplayAlert("1", "Stream Read", "OK");
using (FileStream outputFileStream = new FileStream(filePath, FileMode.Create))
{
fileStream.CopyTo(outputFileStream);
}
await DisplayAlert("2", "Stream Saved", "OK");
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("https://tasmanoperationsportal.azurewebsites.net/UploadFile", content);
Console.WriteLine("App Returned");
await DisplayAlert("Successful", "Photo uploaded to the cloud", "OK");
}
catch
{
await DisplayAlert("Unsuccessful", "No internet connectivity, use default camera App and upload later", "OK");
}
}
Android清单
<?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.tcminspect2_0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
<application android:label="TCmInspect2_0.Android" android:theme="@style/MainTheme" android:requestLegacyExternalStorage="true" ></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>
可以参考Media Picker官方文档 (https://docs.microsoft.com/en-us/xamarin/essentials/media-picker?context=xamarin%2Fandroid&tabs=android)
根据你的代码,你使用后
string filePath = Path.Combine(directory, fN);
就可以使用using (var stream = await file.OpenReadAsync()) using (var newStream = File.OpenWrite(filePath)) await stream.CopyToAsync(newStream); PhotoPath = filePath;
PhotoPath为文件所在路径saved.Then只需要调用PhotoPath即可获取本地存储的图片
我创建了一个简单的示例供您参考(我创建了一个按钮来拍照并将其保存到设备):
cs页面代码如下:
public string PhotoPath { get; set; } = null;
public MainPage()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
var file = await MediaPicker.CapturePhotoAsync();
await LoadPhotoAsync(file);
if (file == null)
return;
async Task LoadPhotoAsync(FileResult photo)
{
// canceled
if (photo == null)
{
PhotoPath = null;
return;
}
// save the file into local storage
var newFile = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using (var stream = await photo.OpenReadAsync())
using (var newStream = File.OpenWrite(newFile))
await stream.CopyToAsync(newStream);
PhotoPath = newFile;
myImg.Source = PhotoPath;//Show on the front page
}
}
截图如下: