Hololens开发初探踩的一些坑

  微软官方对HoloLens的开发提供了两种常用方法,使用VS2015和Unity HoloLens专用版本。其中VS方式可以利用通用Windows模版Holographic DX11 App生成框架代码,Unity方式可以导入HoloToolkit这个官方推荐的工具集加速开发。

HoloLens运行在Win10系统,其应用程序为UWP App,这种App的权限受到比较大的限制,使用API时务必在Package.appxmanifest或unity设置里申请对应权限。此外,由于HoloLens生态还未成熟,微软目前对其做出了更多的限制,这些限制通常是由于设备特殊性或功能暂未集成造成,有些限制会在未来的版本解除。当前限制可参考:

  1.Current limitations for apps using APIs from the shell

  2.App model

  此外,以下记录实际操作中遇到的一些细节问题,供大家参考。特别注意,曾亲历过同样的API在旧版系统抛异常,但更新系统后可用的情况。因此在不同版本环境下可能出现不同结果,记录问题时使用的环境如下:

开发环境:Win10 X64 10586版本, VS 2015 update3, Unity 5.4.0b24-HTP

HoloLens:10.0.14342.1018版本

一、文件系统

  a.KnownFolder路径获取方式的异同

  UWP程序的文件操作使用Windows.Storage命名空间的API,其中最常用的一个类为KnownFolders。这个类包括常用目录的属性和获取目录的方法,例如相机胶卷目录这个常用目录,可以使用两种方式获取,返回类型都为StorageFolder。

  1. 使用属性KnownFolders.CameraRoll
  2. 使用方法KnownFolders.GetFolderForUserAsync(null, KnownFolderId.CameraRoll); 第一个参数为User,通过微软在Github的Sample Code可知指定null代表当前用户。

  当前MSDN文档并未说明二者的区别,实际使用时会发现返回值中的路径域有所不同:

  方法1为C:\Data\Users\DefaultAccount\Pictures\Camera Roll

  方法2为C:\Data\Users\DefaultAccount\AppData\Roaming\Microsoft\Windows\Libraries\ CameraRoll.library-ms

  注意:

  如使用Windows.Storage的文件类StorageFile来操作枚举目录中的文件,则两者没有区别,文件的路径并不受目录路径影响,都会得到形如方法1的路径。如(xxxFolder设为前步返回值):

  IReadOnlyList<StorageFile> fileList = await xxxFolder.GetFilesAsync();

  foreach (StorageFile file in fileList) { /* file.path is the same */ }

  但是,如果需要使用目录路径来拼路径,则需注意!例如Unity的WWW需要路径参数,这里的目录路径需使用方法1的返回路径,使用b会导致无效参数的错误。

  b.暂不能操作的常见目录

  结果:读取即可导致抛异常。

  KnownFolderId.HomeGroup

  KnownFolderId.MediaServerDevices

  KnownFolderId.RemovableDevices

  c.拷贝API的异常

  结果:目标目录已含被拷贝文件,会导致异常。

  如拷贝xFile到xFolder:

  xFile.CopyAsync(xFolder) // Exeption if xFolder already has xFile

  如需强行拷贝需使用如下方法:

  xFile.CopyAsync(xFolder, xName, NameCollisionOption.ReplaceExisting);

  但有个例外,即xFile就在xFolder目录时,上述API仍然会异常。

  d.DP权限问题

  使用DevicePortal从电脑传入HoloLens的文件,权限设置存在问题,普通App无权访问。访问即抛System.UnauthorizedAccessException。

  如:向相机目录传入一张合格照片,Hololens的内置Photo应用是看不到此照片的。

二、权限问题

  a.位置权限

  调用GPS相关API,程序的manifest指定了Location权限,在首次运行时仍然需要一次确认,Hololens App可以调用Launcher.LaunchUriAsync(new Uri("ms-settings:privacy-location"))把系统设置的隐私页弹出,让用户选择允许。操作之后,在模拟器下才可以得到准确的经纬度信息。

  b.用户账户信息权限

  虽然此功能并未列在Hololens官方的限制列表,实测时发现用户账户信息枚举不到,但同样代码在普通Win10设备可以成功获取。这一点也作为试出的当前差异,列此备忘。

时间: 2024-08-05 03:29:30

Hololens开发初探踩的一些坑的相关文章

&quot;开发路上踩过的坑要一个个填起来————持续更新&#183;&#183;&#183;&#183;&#183;&#183;(7月30日)&quot;

欢迎转载,请注明出处! https://gii16.github.io/learnmore/2016/07/29/problem.html 踩过的坑及解决方案记录在此篇博文中! 个人理解,如有偏颇,欢迎指出! 欢迎交流! 3.scss和css的区别 在使用github pages的jekylltheme时,发现有一个scss文件,略感好奇.查了一下,scss文件是css预处理器所产生的中间文件,可通过编译产生css文件.简单说起来就是,程序员觉得CSS只能一行一行的手动添加实在是太麻烦.于是大家

Android 开发中踩过的坑之六:几个关于View的tips

这几个点, 不算是坑, 但是也确实浪费了我一些时间 1.ScrollView的高设置成"wrap_content"会缩的很小,  ScrollView内只允许嵌套一个View, 并且不要将他的高度设置为"wrap_content", 否则它会缩小到很短的样子. ListView也是一样. 2.ListView中的Item如果有不同的样式,最好使用getItemViewType()来区别 事实上, 在ListView的Item完全可以用一种View布局来控制Visia

Android 开发中踩过的坑之十一: 团队协作的坑

工作中,android的坑很多,一部分是android源码自身的逻辑陷阱, 但跟多的是自己和同事们由于种种原因埋下的坑. 提高面向对象的能力,并恰当的实现在代码中,能够极大的减少坑人和被坑几率. 面向对象的最大特征是复用, 复用的目的是减少工作量,减少错误几率,提高工作效率. 总结几个自己的体会,以自勉: 1 在编码前明确代码的模块框架, 定义最简单的接口. 有人也许说, 书生造反,十年不成, 在工期紧张或者其他类似敏捷编程的大背景下, 先干起来才是硬道理. 事实上, 工期紧张也许正是因为之前的

Android 开发中踩过的坑之七:尽量避免使用Acitivity当做Context

这坑容易埋, 却不容易发现. 比如启动一个页面, 需要用到一个单例的工具类Utils, 初始化Utils需要一个Context参数, 直接传入Activity.this. 然后这个单例的Utils就会一直持有Activity.this, 导致整个Acitivity不能被GC. 而如果代码中大量的使用Utils, 又不能确认到底谁最先初始化了Utils, 使得内存泄露成了灵异事件难以发现. 所以, 正确的使用方式是: activity.this.getApplicationContext(); g

Android 开发中踩过的坑之八:多进程问题

这是个需要细心处理的坑. 1 内存: 在manifest中可以对各个组件声明其所在的进程: android:process=":name" 然后对应的Acitivity, Receiver, Service就会运行在相应的进程中. 但是有些类会在所有进程中运行, 比如一些Utils工具类, 比如Application类. 当遇到多个进程并行的时候, 厘清进程所对应的代码, 避免在进程A里跑了进程B的代码. 比如有一个工具类Utils_procA. 只需要在进程A中工作, 那对于进程B来

Android 开发中踩过的坑之二: 16ms的UI线程时间才不会卡顿

AndroidUI卡顿, 是总会遇到的问题, 这个坑经常遇到, 通常在优化时才会重点关注. 通常在Adapter.getView()方法中比较突出. 人眼的原因, 1秒24帧的动画才能感到顺畅. 所以每帧的时间大概有41ms多一点点(1000ms/24). 但是但是, 注意了, 这41ms不是全都留给你java代码, 而是所有java native 屏幕等等的, 最后留给我们用java级别发挥的时间, 只有16~17ms了. 所以,当你优化视觉效果时, 留意UI线程的时间, 超过16ms, 就需

那些年,我们在Django web开发中踩过的坑(一)——神奇的‘/’与ajax+iframe上传

一.上传图片并在前端展示 为了避免前端整体刷新,我们采用ajax+iframe(兼容所有浏览器)上传,这样用户上传之后就可以立即看到图片: 上传前: 上传后: 前端部分html: <form style="display: inline-block" id="upload_img_form" name="form" action="/upload/" method="POST" enctype=&qu

Android 开发中踩过的坑之四:低版本使用AsyncTask

这个坑比较隐晦, 一般不容易出现. 有可能在使用AsyncTask时, 明明就是在postResult()方法里设置UI, 却被告知不能在非UI线程设置UI的异常. 这实际上应用App启动时的一个bug. AsyncTask是在初始化的时候, 自己取当前的线程获取Looper. 但是问题来了, 当前线程可能并不是UI线程, 所以就导致了postResult()等原本应该在UI线程工作方法, 实际上在非UI线程. 谷歌在4.1以后版本里解决这个bug, 就是在应用启动时, 在UI线程里先调用了一次

Android 开发中踩过的坑之十: 谨慎处理动画的开始和结束

Android提供多种动画机制, 从面相对象的方式到直接实现底层onDraw的方式, 给予了足够的控件实现希望的效果, 无论时使用哪种方式实现动画, 都要谨慎的处理动画的两个状态, 开始和结束 需要关注的问题有: 1 动画开始的时候是否需要重新初始化内存? 对于需要重复展示的动画, 应当避免每次都new新的内存, 否则在动画展示过程, 内存会不断增加, 而gc合适回收, 是不确定的. 也许当gc时, 你已经在OOM的边缘了. 2 动画开始时是否是从某个中间状态开始的? 动画从某个中间状态开始,