原文地址:http://blog.danlew.net/2014/11/26/i-dont-need-your-permission/
在Android上从一个用户角度得到授权是棘手的。通常你只想做一些次要的或者无伤大雅的事情(用一个联系人信息提前填充表格),但是你必须要求给你比通常的更多的真正的许可(访问所有联系人详细信息)。
用户对你持怀疑态度是可以理解的。如果你的app是闭源的,那么他们就没有验证的方式你是否正在下载他们的所有的联系人到它们的服务器。甚至如果你解释这个许可,人们也不会相信你。在过去,为了避免用户不信任,我选择不实现那些容易取得的特性。
也就是说,困扰我的一件事情是你有时候不得不请求授权来做一些事情。
恰当的例子:android.permission.CALL_PHONE。你需要它从你的app中启动打电话,是吗?你打电话不就是这样吗?
Intent intent = new Intent(Integer.ACTION_CALL); intent.setData(Uri.parse("12345678910")); startActivity(intent);
错了!原因是你需要许可,因为在没有用户操作的情况下,在任何时候你可以通过代码开启一个phone call。如果我的app有了这个许可,那么我就能在每天的早上的半夜3点拨打1-900-CAT-FACTS而且你可以做到神不知鬼不觉。
做这个更正确的方式是要么使用ACTION_VIEW或者ACTION_DIAL:
Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("12345678910")); startActivity(intent);
这个解决方案的漂亮之处就是你不需要许可。你不需要的原因是因为代替开启一个通话,它使用前面的电话号码运行了一个Dialer应用程序,但是还是任然要求用户需要点击"拨打"来开启通话。说实话,总之这感觉像是一个更好的系统;我不想app让我大吃一惊。
另一个例子:当我的妻子抱怨为了在她的电话上得到导航需要点击很多次,我就为我的妻子写了个Quick Map。她所想要的就是她的联系人列表和导航到它们的一种方式。
你也许认为我为了写这个app需要为了获取所有联系人得到许可:又错了!如果你看了源代码,你将看到为了取出一个地址,使用了ACTION_PICK来运行另一个app:
Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(StructuredPostal.CONTENT_TYPE); startActivityForResult(intent,1);
做了这个不仅仅意味着你获得了许可请求,它也意味着我的app不需要任何UI。它完全利用你要选择的联系人的应用程序的UX。
Android的最酷的其中之一是Intent系统,因为它意味着不需要我到处写代码。其它的应用程序能注册它们自己取得期望的指定的数据片段,像电话号码,短信或者联系人。如果必须都由我来做它,那么我的应用程序可能很多时候就是一个bug程序,因为那需要很多的工作量。
这个系统的另一个好处是在我没有请求它们的情况下我自己能利用那些其它的app的许可。本质上也就是所有上面提到的。然而拨打一个app需要能make call的许可,我的Intent打开这个拨打器,但是不拨打。总而言之,用户相信拨打器来make call而不是我的app。
这个故事的寓意是在你考虑添加许可以前,你应当至少详细了解 Intent文档来看看是否有其它的请求另一个app的方式来为你做这件事。如果你真的想深入了解,你能学习更多错综复杂的许可系统详述,它包含了取得许可更多的方式。
使用更少的许可将不仅仅让你得到更多用户信任,而且用户将有更好的体验,因为他们也将变得使用他们首选的app。