|
9 | 9 | * 校对者:
|
10 | 10 | * 状态 : 翻译中
|
11 | 11 |
|
12 |
| -With Marshmallow a new permissions model was added to Android which requires developers to take a somewhat different approach to permissions on Android. In this series we’ll take a look at ways to handle requesting permissions both from a technical perspective, and in term of how to provide a smooth user experience. |
13 |
| - |
14 | 12 | 在Marshmallow(棉花糖,Android6.0版本)中Android添加了一个新的权限模块,需要开发者在授权的时候做一些不同的处理。在这一系列中,我们从技术角度看下如何处理请求的权限和如何提供流畅的用户体验。
|
15 | 13 |
|
16 | 14 | 
|
17 | 15 |
|
18 |
| -Previously we looked at how we can incorporate the logic for checking that we have the required permissions, but next we’ll look at how we can actually request the permissions that haven’t been granted. |
19 |
| - |
20 | 16 | 我们已经知道了如何检测我们需要的权限,现在我们看下如何请求被拒绝的权限。
|
21 | 17 |
|
22 |
| -The happy flow (for us as developers, at least) for this is that we ask the user to explicitly grant us a required permission, the user grantes it and everyone is happy. But, as we discussed previously, we need to cover the cases where the user denies us the permission we’ve requested. |
23 |
| - |
24 | 18 | 令人高兴的流程是(至少对于开发者来说),我们直接询问用户授权需要的权限,用户授权了,大家都高兴。但是,就像我们之前讨论过的,我们需要考虑到用户没有授予权限的情况。
|
25 | 19 |
|
26 |
| -Let’s first look at the logic for the happy path as this is relatively straightforward: |
27 |
| - |
28 | 20 | 现在让我们看下,我们直接提出请求的操作:
|
29 | 21 |
|
30 | 22 | PermissionsActivity.java
|
@@ -87,12 +79,8 @@ public class PermissionsActivity extends AppCompatActivity {
|
87 | 79 | }
|
88 | 80 | ```
|
89 | 81 |
|
90 |
| -We have a startActivityForResult() method which is a simple utility method which other Activities must use to start the PermissionsActivity with a given set of required permissions. So the flow is pretty straightforward once we have the required permissions. However, you may be wondering why we need this – surely we launched the Activity because we already determined that we don’t have the required permissions? The reason that we need this is for some of the following edge cases – if the user leaves this Activity temporarily, and grants the permission in Settings, then returns then this flow will be followed. |
91 |
| - |
92 | 82 | 我们有一个非常实用的startActivityForResult()方法,其他Activity必须使用这个传入需要请求的一套权限来启动PermissionsActivity。所以我们可以直接一次都请求所需要的权限。然而,你可能会疑惑我们为什么需要这个-我们启动Activity是因为我们已经知道我们没有获得所需要的权限么?我们需要这个的原因是如下的这些小概率情况-如果用户临时离开了这个Activity,在设置中授权了权限,然后再回来的时候这个流程会次执行。
|
93 | 83 |
|
94 |
| -But what about when we don’t have the required permissions – we’ll need to request them: |
95 |
| - |
96 | 84 | 但是当我们没有所需要的权限时怎么办-我们需要请求它们:
|
97 | 85 |
|
98 | 86 | PermissionsActivity.java
|
@@ -130,16 +118,10 @@ public class PermissionsActivity extends AppCompatActivity {
|
130 | 118 | .
|
131 | 119 | ```
|
132 | 120 |
|
133 |
| -This is the core of the process. We call requestPermissions() which passes control to the OS to request the permissions that we require. I always make a point of passing both normal and dangerous level permissions here even though we get automatically granted normal permissions. The reasoning behind this is that if what is now considered a normal permission was changed to a dangerous permission in the future then everything would still work. |
134 |
| - |
135 | 121 | 这就是处理核心。我们调用requestPermissions()请求我们需要的权限。我这里总是强调标准和危险级别的权限,虽然我们自动获得标准的权限。背后的原因是,如果标准权限在未来变为一个危险的权限,那么仍会正常工作。
|
136 | 122 |
|
137 |
| -requestPermissions() operates in a similar manner to startActivityForResult() – we pass control to another Activity and then get a callback once that Activity completes. In this case the callback method is onRequestPermissionResult(). This checks that all of the requested permissions have been granted and either passes control back (either through finish() or invoking MainActivity, as before), or things become a little more complex: We have requested the required permission, and the user has denied it. |
138 |
| - |
139 | 123 | requestPermissions()的操作和startActivityForResult()的操作很像 - 我们在另一个Activity中处理,然后在本Activity中用一个回调做为结束。这个例子中的回调函数是onRequestPermissionResult()。它检测了所有被授权的权限和要么返回处理(要么通过finish(),要么重新唤醒MainActivity,就像之前那样),要么事情变为稍有复杂:我们请求所需要的权限但用户拒绝了。
|
140 | 124 |
|
141 |
| -The first time we ask the user for a particular permission following installation the user will be given with a simple choice: Allow or deny. If they deny us permission and we request it again they will also have a checkbox labelled “Never ask again”. If the user checks this and taps “Deny” then any subsequent requests that we make for the same permission will automatically be denied. Unfortunately we have no way of knowing if this has happened we will just get a PERMISSION_DENIED response. Bearing in mind that this particular permission is critical to the operation of this app we need to further inform the user of why this permission is required and, if they still refuse to grant it, exit the app: |
142 |
| - |
143 | 125 | 首先,安装时我们会问用户一个特殊的权限,用户可以选择:允许或拒绝。如果拒绝了权限,我们会在此请求,这时会有一个单选框“不再询问”。如果用户选择了一个单选框并按了“拒绝”,之后的任何权限请求都会被自动的拒绝。不幸的是,我们的权限被拒绝了,我们并不知道用户是否执行了上面的操作。考虑到这个特殊的权限是App运行所急需的,我们需要明确告诉用户为什么我们需要这个权限,如果仍然被拒绝,那就退出App:
|
144 | 126 |
|
145 | 127 | PermissionsActivity.java
|
@@ -177,33 +159,20 @@ public class PermissionsActivity extends AppCompatActivity {
|
177 | 159 | }
|
178 | 160 | ```
|
179 | 161 |
|
180 |
| -I have deliberately kept the actual text used here somewhat vague because every app will need to explain its precise reasons for needing the permission in question. Also, for the sake of clarity, I have no way of providing different information for different permissions as only one dangerous permission is being requested. However is a real app you will probably need to determine which permission is missing and provide appropriate information for each. |
181 |
| - |
182 | 162 | 我故意让这里的说明文本说的有点含糊,因为每一个app都要解释需要这个权限的具体原因。同样,为了清晰明了,当只有一个危险权限被请求时,我没有办法没有针对不同权限提供不同的信息。然而,一个真实的app,你很可能需要确定哪一个权限缺失了和针对每一个缺失的提供一个恰当的描述信息。
|
183 | 163 |
|
184 |
| -So here we can see the flow when the user initially denies the permission, exits and subsequently grants the permission: |
185 |
| - |
186 | 164 | 这里我们可以看到当用户最初拒绝了这个权限,退出和后来的权限的授予。
|
187 | 165 |
|
188 | 166 | [video](https://youtu.be/0YBb_lmsyIM)
|
189 | 167 |
|
190 |
| - |
191 |
| -If the user permanently denies permission (by checking “Never ask again”) the flow becomes a little more complex for the user because we cannot provide a link directly to the Permissions Settings page for our app so we need to provide some instructions to help the user: |
192 |
| - |
193 | 168 | 如果用户永远拒绝了权限(通过“不再提醒”选择框)。接下来会稍微复杂,因为我们不能提供一个我们app权限设置页面的直接链接,所以我们需要给用户提供一些说明:
|
194 | 169 |
|
195 | 170 | [video](https://youtu.be/gqFIJvMqIpQ)
|
196 | 171 |
|
197 |
| -It would be nice if we could alter the flows between the two kinds of denial. The first video shows that we have to tell the user to alter things through Settings even though we subsequently see that exit and re-launch prompts them once again to allow or deny. Unfortunately we have no way of knowing if the user has selected “Never ask again” so we have to work against the worst-case scenario. |
198 |
| - |
199 | 172 | 需要注意的是是否我们改变了这两者之间的流程。第一个视频展示的是我们告知用户通过设置改变,即使我们随后看到了退出和重新启动后再次提示的允许或拒绝。不幸的,我们没有办法知道用户是否选择了“不再提示”,所以我们要做最坏情况的打算。
|
200 | 173 |
|
201 |
| -That said we now have a relatively simple, reusable method of requesting the critical permissions for our app. In the final article in this series we’ll look at non-critical permissions and consider some best practise. |
202 |
| - |
203 | 174 | 即便如此我们现在有一个相对简单,可以重复使用的请求我们应用关键权限的方法。在这个系列的最后一篇文章我们来看看非关键权限和更多的练习。
|
204 | 175 |
|
205 |
| -The source code for this article is available [here](https://github.com/StylingAndroid/Permissions/tree/Part3). |
206 |
| - |
207 | 176 | 源代码在[这里](https://github.com/StylingAndroid/Permissions/tree/Part3)。
|
208 | 177 |
|
209 | 178 | © 2016, [Mark Allison](https://blog.stylingandroid.com/). All rights reserved.
|
|
0 commit comments