问题描述
我正在尝试将图像加载到应用程序中。我正在关注 MS 文档 https://docs.microsoft.com/en-us/xamarin/essentials/media-picker?tabs=android。虽然 UWP 运行良好(仅使用模拟器测试),但我无法让它在 Android 上运行(也仅使用模拟器测试)。应用程序会用照片保存位置。我不知道这是否重要,但第一页是地图,显示当前位置,第二页是我想保存位置和照片的错误页面。
当我选择照片时,它会清除页面(以防条目和编辑器中的任何内容都被清除)并且不显示图片。即使带有照片路径的标签也不会返回任何内容。这就像它重新加载页面。我实现了以相同结果拍照的选项。
在调试模式下,所有属性都有值,但当我选择/拍摄照片时,属性值不会显示在 UI 上。
视图模型
using iVanApp.Model;
using iVanApp.Services;
using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;
using Xamarin.Essentials;
using System.Threading;
using System.Linq;
using Xamarin.Forms.Maps;
using System.Threading.Tasks;
using System.IO;
namespace iVanApp.viewmodels
{
class AddNightviewmodel : Baseviewmodel
{
public AddNightviewmodel(INavService navService)
: base(navService)
{
}
CancellationTokenSource cts;
string comment;
public string Comment
{
get => comment;
set
{
comment = value;
OnPropertyChanged();
}
}
string nameNight;
public string NameNight
{
get => nameNight;
set
{
nameNight = value;
OnPropertyChanged();
}
}
private async Task<string> GetAddressName(Location location)
{
Geocoder geoCoder = new Geocoder();
// Position position = new Position(latitude.Value,longitude.Value);
Position position = new Position(location.Latitude,location.Longitude);
string address = String.Empty;
try
{
IEnumerable<string> possibleAddress = await geoCoder.GetAddressesForPositionAsync(position);
address = possibleAddress.FirstOrDefault();
await Application.Current.MainPage.displayAlert("Succes!","Saved. Address is " + address,"OK");
}
catch (Exception ex)
{
await Application.Current.MainPage.displayAlert("Error!","Something went wrong\nError:\n" + ex.Message,"OK");
}
return address;
}
public Command SaveLocation
{
get
{
return new Command(async () =>
{
var location = await Geolocation.GetLastKNownLocationAsync();
if (location == null)
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium,TimeSpan.FromSeconds(10));
cts = new CancellationTokenSource();
location = await Geolocation.GetLocationAsync(request,cts.Token);
}
string addressName = string.Empty;
if (location != null)
{
addressName = await GetAddressName(location);
}
Night nightData = new Night
{
NightDate = DateTime.Now.Date,NightLatitude = location.Latitude,NightLongitute = location.Longitude,NightName = NameNight,Address = addressName,Comments = Comment,Nightimage = PhotoPath
};
await App.Database.SaveNightAsync(nightData);
});
}
}
string photoPath;
public string PhotoPath
{
get => photoPath;
set
{
photoPath = value;
OnPropertyChanged();
}
}
public Command SelectPhoto
{
get
{
return new Command(async () =>
{
try
{
var photo = await MediaPicker.PickPhotoAsync();
await LoadPhotoAsync(photo);
Console.WriteLine($"CapturePhotoAsync COMPLETED: {PhotoPath}");
await Application.Current.MainPage.displayAlert("Done",$"CapturePhotoAsync COMPLETED: {PhotoPath}","OK");
}
catch (Exception ex)
{
Console.WriteLine($"CapturePhotoAsync THREW: {ex.Message}");
await Application.Current.MainPage.displayAlert("ERROR",$"CapturePhotoAsync THREW: {ex.Message}","OK");
}
});
}
}
public Command TakePhoto
{
get
{
return new Command(async () =>
{
try
{
var photo = await MediaPicker.CapturePhotoAsync();
await LoadPhotoAsync(photo);
//Console.WriteLine($"CapturePhotoAsync COMPLETED: {PhotoPath}");
await Application.Current.MainPage.displayAlert("Done","OK");
}
catch (Exception ex)
{
//Console.WriteLine($"CapturePhotoAsync THREW: {ex.Message}");
await Application.Current.MainPage.displayAlert("Error","OK");
}
});
}
}
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;
}
}
}
查看
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="iVanApp.Views.AddNightView">
<ContentPage.Content>
<StackLayout>
<Entry Text="{Binding NameNight}"/>
<Editor Placeholder="Comments"
Text="{Binding Comment}"/>
<Button Text="Choose photo"
Command="{Binding SelectPhoto}"
/>
<Button Text="Take photo"
Command="{Binding TakePhoto}"
/>
<Button Text="Save location"
Command="{Binding SaveLocation}"/>
<Label Text="{Binding PhotoPath}"/>
<Image Source="{Binding PhotoPath}"
HeightRequest="150"
Aspect="AspectFit"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Andoid 权限- AssemblyInfo
// Needed for Picking photo/video
[assembly: UsesPermission(Android.Manifest.Permission.ReadExternalStorage)]
// Needed for Taking photo/video
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
[assembly: UsesPermission(Android.Manifest.Permission.Camera)]
02-25 01:10:00.293 W/ActivityThread(28782): handleWindowVisibility: no activity for token android.os.BinderProxy@f3053de
02-25 01:10:00.299 E/SchedPolicy(28782): set_timerslack_ns write Failed: Operation not permitted
02-25 01:10:00.440 D/EGL_emulation(28782): eglMakeCurrent: 0xc7cd21e0: ver 3 0 (tinfo 0xc7cfc0d0)
02-25 01:10:00.499 I/chatty (28782): uid=10092(com.companyname.ivanapp) RenderThread identical 2 lines
02-25 01:10:00.524 D/EGL_emulation(28782): eglMakeCurrent: 0xc7cd21e0: ver 3 0 (tinfo 0xc7cfc0d0)
02-25 01:10:01.270 D/EGL_emulation(28782): eglMakeCurrent: 0xc7cd21e0: ver 3 0 (tinfo 0xc7cfc0d0)
CapturePhotoAsync COMPLETED: /data/user/0/com.companyname.ivanapp/cache/IMG_20210224_063027.jpg
02-25 01:10:02.231 I/mono-stdout(28782): CapturePhotoAsync COMPLETED: /data/user/0/com.companyname.ivanapp/cache/IMG_20210224_063027.jpg
02-25 01:10:02.312 W/StaticLayout(28782): maxLineHeight should not be -1. maxLines:2 lineCount:2
02-25 01:10:02.320 I/chatty (28782): uid=10092(com.companyname.ivanapp) identical 5 lines
02-25 01:10:02.320 W/StaticLayout(28782): maxLineHeight should not be -1. maxLines:2 lineCount:2
02-25 01:10:02.499 D/EGL_emulation(28782): eglMakeCurrent: 0xc7cd21e0: ver 3 0 (tinfo 0xc7cfc0d0)
02-25 01:10:02.708 D/EGL_emulation(28782): eglMakeCurrent: 0xc7cd21e0: ver 3 0 (tinfo 0xc7cfc0d0)
02-25 01:10:04.406 D/EGL_emulation(28782): eglMakeCurrent: 0xc7cd21e0: ver 3 0 (tinfo 0xc7cfc0d0)
02-25 01:10:04.408 D/Openglrenderer(28782): endAllActiveAnimators on 0xc12e6400 (rippledrawable) with handle 0xc12a9d20
02-25 01:10:04.418 E/SchedPolicy(28782): set_timerslack_ns write Failed: Operation not permitted
02-25 01:10:04.440 D/EGL_emulation(28782): eglMakeCurrent: 0xc7cd21e0: ver 3 0 (tinfo 0xc7cfc0d0)
任何帮助/见解将不胜感激。
更新
我试图找到一个问题并从头开始构建一个测试应用程序并测试 MediaPicker 何时停止工作。当我实现导航时会发生这种情况。我根据 Mastering Xamarin.Forms 一书做了导航(只有在开始使用框架时才达到部分。所以我是没有框架的导航)。
我的导航正在跟踪
INavService
public interface INavService
{
// Navigatze to another page without passing any parameter
Task Navigateto<TVM>()
where TVM : Baseviewmodel;
}
XamarinFormsNavService
[assembly: Dependency(typeof(XamarinFormsNavService))]
namespace TestMediaPicker_v2.Services
{
public class XamarinFormsNavService : INavService
{
readonly IDictionary<Type,Type> _map = new Dictionary<Type,Type>();
// Creates dictionary of all viewmodels and coresponding Views
public void RegistryViewMapping(Type viewmodel,Type view)
{
_map.Add(viewmodel,view);
}
public INavigation XamarinFormsNav { get; set; }
// Navigation task for each viewmodel and coresponding View
public async Task Navigateto<TVM>() where TVM : Baseviewmodel
{
await NavigatetoView(typeof(TVM));
if (XamarinFormsNav.NavigationStack.Last().BindingContext is Baseviewmodel)
{
((Baseviewmodel)XamarinFormsNav.NavigationStack.Last().BindingContext).Init();
}
}
async Task NavigatetoView(Type viewmodelType)
{
if (!_map.TryGetValue(viewmodelType,out Type viewType))
{
throw new ArgumentException("No view found in view mapping for " + viewmodelType.FullName + ".");
}
// Use reflection to get the View's constructor and create an instance of the View
var constructor = viewType.GetTypeInfo()
.DeclaredConstructors
.FirstOrDefault(dc => !dc.GetParameters().Any());
var view = constructor.Invoke(null) as Page;
await XamarinFormsNav.PushAsync(view,true);
}
}
}
我的观点背后的代码
protected override async void OnAppearing()
{
var viewmodel = new AddNightviewmodel(DependencyService.Get<INavService>());
BindingContext = viewmodel;
}
app.xaml.cs 中的视图和视图模型字典
public App()
{
InitializeComponent();
var mainPage = new NavigationPage(new AddNightView());
var navService = DependencyService.Get<INavService>() as XamarinFormsNavService;
navService.XamarinFormsNav = mainPage.Navigation;
navService.RegistryViewMapping(typeof(AddNightviewmodel),typeof(AddNightView));
navService.RegistryViewMapping(typeof(AllNightsviewmodel),typeof(AllNightsView));
MainPage = mainPage;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)