假设你有一个这样的方法:
public boolean saveFile (Url url, String content) {
// save the file, this can be done a lot of different ways, but
// basically the point is...
return save_was_successful;
}
在整个应用程序中,如果您想将文件保存到外部存储,您可以执行类似...
if (saveFile(external_storage_url, "this is a test")) {
// yay, success!
} else { // notify the user something was wrong or handle the error }
这是一个简化的例子,所以不要在我的情况下阻止 UI,正确处理异常等。如果你不喜欢文件保存,你可以想象一个
getContact()
或 getPhoneState()
管他呢。关键是它是一个需要权限的操作,它返回一些值,并在整个应用程序中使用。在 Android <= Lollipop 中,如果用户已安装并同意授予
android.permission.WRITE_EXTERNAL_STORAGE
或者别的什么,一切都会好的。但是在新的棉花糖 (API 23) 中 runtime permission model , 在您可以将文件保存到外部存储之前,您应该 (1) 检查是否已授予权限。 If not , 可能 (2) show a rationale for the request (如果 system thinks it's a good idea )祝酒或其他任何东西和(3)要求用户通过对话框授予权限,然后基本上坐下来等待回调......
(所以你的应用程序坐在那里,等待......)
(4) 当用户最终响应对话框时,onRequestPermissionsResult()方法触发,您现在的代码 (5) 必须筛选 WHICH permission要求他们实际上是 responding to ,无论用户说是或否(据我所知,没有办法处理“不”与“不,不要再问”),(6) 弄清楚他们首先试图完成的提示是什么整个请求权限过程,以便程序最终可以 (7) 继续执行该操作。
要了解用户在步骤 (6) 中尝试执行的操作涉及先前已通过特殊的 code (“权限请求响应”)在文档中被描述为 permission request 类型的标识符(相机/联系人/等)但在我看来更像是“特别是当您意识到需要请求权限时您正在尝试做的事情”代码,因为相同的权限/组可能用于多个在您的代码中使用目的,因此您需要在获得许可后使用此代码将执行返回到适当的位置。
我可能完全误解了这应该如何工作 - 所以如果我离开了,请告诉我 - 但更重要的是我真的不知道如何考虑使用上述所有内容
saveFile()
由于异步“等待用户响应”部分,前面描述的方法。我考虑过的想法非常老套,而且肯定是错误的。今天的 Android Developer Podcast暗示可能有一种同步解决方案即将到来,甚至有人谈到了 Android Studio 中一种神奇的、一步式 alt-enter 类型的“添加权限请求”工具。尽管如此,运行时权限过程可能如何被插入
saveFile()
或者别的什么——我在想一些事情:public boolean saveFile(Url url, String content) {
// this next line will check for the permission, ask the user
// for permission if required, maybe even handle the rationale
// situation
if (!checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
R.string.permission_storage_rationale))
{
return false; // or throw an exception or whatever
} else {
// try to save the file
return save_was_successful;
}
}
所以上面的
checkPermission()
如果用户没有并且拒绝授予权限,则会失败。也许可以在 checkPermission()
周围使用循环尝试最多询问 3 次或其他什么,或者更好的是,如果该方法处理了一个理智的不要惹人厌的政策。这样的事情可能吗?可取?任何这样的解决方案会阻止 UI 线程吗?从播客看来,谷歌可能有这样的解决方案即将到来,但我想知道是否有什么东西——一个便利类,一个模式,什么东西——不需要每个人都必须重构所有需要许可的操作,我必须假设这可能会变得非常困惑。
抱歉这个冗长的问题,但我想尽可能完整。我将取消我的回答。谢谢!
更新 :这是上述播客的成绩单。
收听关于 41:20 .在本次讨论中:
粗略抄录:
Tor Norbye(工具团队):“所以对于开发人员来说,这似乎不应该是很多工作。但我理解部分问题在于这些不是同步调用,对吧?。所以你必须 - 实际上改变你的 Activity 的编写方式,让它有一个回调——所以它真的有点像一个状态机......对于这个状态,你——”
Poiesz(产品经理):“啊——我想——有一个——可能有一个同步响应的选项——”
诺拜:“哦。那会让事情——”
Poiesz:“我可以与内部人员交谈。我记得有一次关于同步的讨论——但我们可以找到答案。”
Norbye:“是的。事实上,我们可能应该将它纳入工具中。如果你有一个简单的重构......”
然后他谈到在工具中使用注释来确定哪些 API 需要权限..(到目前为止,IMO 的工作方式不是很好),以及他希望工具有一天能够在发现未经检查的“危险”代码时实际生成所需的代码"方法调用:
Norbye:“......那么如果你也在 M 上,它会说,'嘿,你真的在检查这个权限还是你在捕捉安全异常?',如果你不是,我们会说“你可能需要做一些事情来请求这里的许可。”但我想要的是快速修复,你可以去'CHING!'它插入了所有正确的东西来询问,但是当我看到时,事情又回来了,这需要重构很多东西——添加接口(interface)和回调,并改变流程,这是我们做不到的。但如果有一个简单的同步模式作为临时或永久的东西,那会[很棒]。”
最佳答案
至于棉花糖,我的理解是你不能。
我必须在我的应用程序中解决同样的问题。这是我如何做到的:
.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SOME_PERMISSION) == PackageManager.PERMISSION_GRANTED)
doStuffThatRequiresPermission();
else
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SOME_PERMISSION}, Const.PERM_REQUEST_DO_STUFF_THAT_REQUIRES_PERMISSION);
onRequestPermissionsResult()
编写一个实现在每个 Activity
要求权限。检查请求的权限是否被授予,并使用请求代码来确定需要调用什么方法。 请注意,该 API 需要
Activity
用于运行时权限请求。如果您有非交互式组件(例如 Service
),请查看 How to request permissions from a service in Android Marshmallow有关如何解决此问题的建议。基本上,最简单的方法是显示一个通知,然后显示一个 Activity
它只显示运行时权限对话框。 Here是我在我的应用程序中解决这个问题的方法。
关于android - 您可以在 Android Marshmallow (API 23) 的运行时权限模型中同步请求权限吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32134299/