MediaPicker - 当我选择照片时,它不会显示在页面上,而只会在 Android 上显示

问题描述

我正在尝试将图像加载到应用程序中。我正在关注 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 (将#修改为@)