在 Hololens

问题描述

我将 MRTK 用于 hololens 应用程序,我需要选择用户放入其文档文件夹中的文件。我正在尝试访问 FileOpenPicker 并通过按下按钮使用 PickSingleFileAsync() 函数来获取文件,然后将其加载到我的应用中。

这个函数里面的代码基本上就是我在做的:

(Code Source)

private async void PickAFileButton_Click(object sender,RoutedEventArgs e)
        {
            // Clear previous returned file name,if it exists,between iterations of this scenario
            OutputTextBlock.Text = "";

            FileOpenPicker openPicker = new FileOpenPicker();
            openPicker.ViewMode = PickerViewMode.Thumbnail;
            openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            openPicker.FileTypeFilter.Add(".jpg");
            openPicker.FileTypeFilter.Add(".jpeg");
            openPicker.FileTypeFilter.Add(".png");
            StorageFile file = await openPicker.PickSingleFileAsync();
            if (file != null)
            {
                // Application now has read/write access to the picked file
                OutputTextBlock.Text = "Picked photo: " + file.Name;
            }
            else
            {
                OutputTextBlock.Text = "Operation cancelled.";
            }
        }

但是,当我构建并部署到 Hololens Emulator 时,当我按下按钮时它运行代码的第一部分就好了,但我在这一行遇到了异常

StorageFile file = await openPicker.PickSingleFileAsync();

经过广泛的研究和一些挫折,我发表了一篇关于它的非常糟糕和含糊不清的帖子here

在那篇文章中,我引用了 2 年前制作的这个 post,并说您不能这样做,但 The Microsoft docs for Hololens 说您可以使用文件选择器,在本例中为 FileOpenPicker。>

我发现 Windows Mixed Reality Developer Forum 中隐藏的 this 帖子与此相关,但不是我遇到的问题,我仍然觉得有必要将其包含在此帖子中。

我还想补充一点,我确实安装了一个文件选择器应用程序。根据 this post on Microsoft Docs,如果您调用 FileOpenPicker,它将打开您设备上首次安装的任何文件选择器。

也在 MRTK 和正在生成的 Appx 中,我确保启用“PictureLibrary”功能的权限。

非常感谢任何帮助,我觉得我已经等了太久才就这个主题发表更正式的帖子,我希望能得到一些答案。谢谢!

解决方法

ALL THANKS TO THIS POST! 我终于找到了解决我的问题的方法。在我浏览的任何文档中都没有提到的最大调用是这个 UnityEngine.WSA.Application.InvokeOnUIThread()

我没有遇到这个问题,也没有找到任何文档说明这是 MRTK+unity 的 hololens 开发解决方案。因此,对于任何寻求该问题解决方案的人,我将引用上面的链接,以防将来它被破坏。

#if !UNITY_EDITOR && UNITY_WSA_10_0
        Debug.Log("***********************************");
        Debug.Log("File Picker start.");
        Debug.Log("***********************************");

        UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
        {
            var filepicker = new FileOpenPicker();
            // filepicker.FileTypeFilter.Add("*");
            filepicker.FileTypeFilter.Add(".txt");

            var file = await filepicker.PickSingleFileAsync();
            UnityEngine.WSA.Application.InvokeOnAppThread(() => 
            {
                Debug.Log("***********************************");
                string name = (file != null) ? file.Name : "No data";
                Debug.Log("Name: " + name);
                Debug.Log("***********************************");
                string path = (file != null) ? file.Path : "No data";
                Debug.Log("Path: " + path);
                Debug.Log("***********************************");

                

                //This section of code reads through the file (and is covered in the link)
                // but if you want to make your own parcing function you can 
                // ReadTextFile(path);
                //StartCoroutine(ReadTextFileCoroutine(path));

            },false);
        },false);

        
        Debug.Log("***********************************");
        Debug.Log("File Picker end.");
        Debug.Log("***********************************");
#endif

编辑:

稍微解释一下“InvokeOnUIThread”和“InvokeOnAppThread”是什么意思。

想想您的 MRTK 应用程序在 hololens 上运行的方式,您的应用程序在它自己的小环境中运行,并在您的应用程序中使用 MRTK 特定的统一引擎处理函数调用。然后该应用程序在 hololens 的更大应用程序(操作系统)中运行。因此,每当您调用 UWP 特定函数时,只有 hololens 才能理解的内容,您需要在 InvokeOnUIThread 中调用这些函数。现在,当您在该函数调用中运行时,如果您需要将任何函数调用返回到 MRTK、unity 或您自己创建的函数,您需要使用 InvokeOnAppThread。这实质上是告诉应用程序您想要进行一些 UWP 函数调用,然后如果您需要在仍然在 InvokeOnUIThread 调用内部时从 UWP 函数调用传回任何信息,则需要使用 InvokeOnAppThread。

据我所知,这基本上就是整个事情的运作方式,我认为这对记录很重要。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...