【问题标题】:Maui media picker on Windows Platform errorWindows 平台错误上的 Maui 媒体选择器
【发布时间】:2022-06-10 21:25:49
【问题描述】:

我创建了一个非常基本的 MauiApp,因为我想在 Windows 平台上试用 MediaPicker。

于是我复制了官方documentation的代码并尝试运行我的应用程序

但是,如果我按照文档中的建议将 <uap:Capability Name="webcam"/> 添加到 Package.appxmanifest 文件中,然后运行应用程序,则会出现以下错误:

Error       DEP0700: Registration of the app failed. [0x80080204] error 0xC00CE169: App 
manifest validation error: The app manifest must be valid as per schema: Line 39, Column 
21, Reason: 'webcam' violates enumeration constraint of 'documentsLibrary 
picturesLibrary videosLibrary musicLibrary enterpriseAuthentication 
sharedUserCertificates userAccountInformation removableStorage appointments contacts 
phoneCall blockedChatMessages objects3D voipCall chat'.
The attribute 'Name' with value 'webcam' failed to parse.   MauiApp3            
        

所以为了解决这个问题,我尝试将功能从 <uap:Capability Name="webcam"/> 更改为 <DeviceCapability Name="webcam"/>

这样我可以运行应用程序而不会出错,但photo 始终为空:

public async void TakePhoto(object sender, EventArgs e)
{
    if (MediaPicker.Default.IsCaptureSupported)
    {
        FileResult photo = await MediaPicker.Default.CapturePhotoAsync();
        
        if (photo != null)
        {
            // save the file into local storage
            string localFilePath = Path.Combine(FileSystem.CacheDirectory, photo.FileName);

            using Stream sourceStream = await photo.OpenReadAsync();
            using FileStream localFileStream = File.OpenWrite(localFilePath);

            await sourceStream.CopyToAsync(localFileStream);
        }
        else
        {
            // *** IT ALWAYS ENTERS IN THE ELSE CLAUSE ***
            // *** BECAUSE photo IS ALWAYS NULL ***
            CounterBtn.Text = $"Capture is supported but {photo} is null";
        }
    }
}

注意:当我点击我在MainPage.xaml文件中定义的这个按钮时,上面的函数被调用:

        <Button 
            x:Name="ImageBtn"
            Text="Take Photo"
            SemanticProperties.Hint="Take Image"
            Clicked="TakePhoto"
            HorizontalOptions="Center" />

【问题讨论】:

标签: c# .net-6.0 maui .net-maui maui-windows


【解决方案1】:

不幸的是,这是 WinUI3 的一个古老且已知的错误。 microsoft/WindowsAppSDK#1034

作为一种解决方法,您可以创建一个自定义媒体选择器,该媒体选择器继承了适用于 Android、iOS 和 Catalyst 的 MAUI 的所有内容。

然后为 Windows 实现一个自定义媒体选择器,继承所有 Capture... 方法并使用自定义类重新实现 CapturePhotoAsync 用于相机捕捉:

public async Task<FileResult> CaptureAsync(MediaPickerOptions options, bool photo)
{
    var captureUi = new CameraCaptureUI(options);

    var file = await captureUi.CaptureFileAsync(photo ? CameraCaptureUIMode.Photo : CameraCaptureUIMode.Video);

    if (file != null)
        return new FileResult(file.Path,file.ContentType);

    return null;
}

这是新的CameraCaptureUI 类:

using Windows.Foundation.Collections;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.System;
using Microsoft.Maui.Platform;
using WinRT.Interop;

public class CameraCaptureUI
{
    private LauncherOptions _launcherOptions;

    public CameraCaptureUI(MediaPickerOptions options)
    {
        var hndl = WindowStateManager.Default.GetActiveWindow().GetWindowHandle();

        _launcherOptions = new LauncherOptions();
        InitializeWithWindow.Initialize(_launcherOptions, hndl);

        _launcherOptions.TreatAsUntrusted                   = false;
        _launcherOptions.DisplayApplicationPicker           = false;
        _launcherOptions.TargetApplicationPackageFamilyName = "Microsoft.WindowsCamera_8wekyb3d8bbwe";
    }

    public async Task<StorageFile> CaptureFileAsync(CameraCaptureUIMode mode)
    {
        if (mode != CameraCaptureUIMode.Photo)
        {
            throw new NotImplementedException();
        }

        var currentAppData = ApplicationData.Current;
        var tempLocation = currentAppData.TemporaryFolder;
        var tempFileName = "CCapture.jpg";
        var tempFile = await tempLocation.CreateFileAsync(tempFileName, CreationCollisionOption.GenerateUniqueName);
        var token = Windows.ApplicationModel.DataTransfer.SharedStorageAccessManager.AddFile(tempFile);

        var set = new ValueSet
        {
            { "MediaType", "photo"},
            { "PhotoFileToken", token }
        };

        var uri    = new Uri("microsoft.windows.camera.picker:");
        var result = await Windows.System.Launcher.LaunchUriForResultsAsync(uri, _launcherOptions, set);
        if (result.Status == LaunchUriStatus.Success)
        {
            return tempFile;
        }

        return null;
    }
}

唯一的缺点是这个课程你不能在 Windows 上拍摄视频。

还在 Package.appxmanifest 中添加这些功能:

<DeviceCapability Name="microphone"/>
<DeviceCapability Name="webcam"/>

Credits for the CameraCapture class

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2012-01-03
    • 2011-04-09
    • 1970-01-01
    • 2012-03-02
    • 2013-12-04
    • 1970-01-01
    相关资源
    最近更新 更多