1page.title=權限 2page.tags=previewresources, androidm 3page.keywords=權限, 執行階段, 預覽 4page.image={@docRoot}preview/features/images/permissions_check.png 5@jd:body 6 7 8<div id="qv-wrapper"> 9 <div id="qv"> 10 <h2>快速檢視</h2> 11 <ul> 12 <li>如果您的應用程式是以 M 預覽版 SDK 為目標,它會提示使用者在執行階段授與權限,而不是安裝期間。 13</li> 14 <li>使用者能隨時從應用程式 [設定] 畫面撤銷權限。 15</li> 16 <li>您的應用程式每次執行時都需要檢查它是否有所需的權限。 17</li> 18 </ul> 19 20 <h2>本文件內容</h2> 21 <ol> 22 <li><a href="#overview">總覽</a></li> 23 <li><a href="#coding">編寫執行階段權限的程式碼</a></li> 24 <li><a href="#testing">測試執行階段權限</a></li> 25 <li><a href="#best-practices">建議做法</a></li> 26 </ol> 27 28<!-- 29 <h2>Related Samples</h2> 30 <ol> 31 <li></li> 32 </ol> 33--> 34 35<!-- 36 <h2>See also</h2> 37 <ol> 38 <li></li> 39 </ol> 40--> 41 </div> <!-- qv --> 42</div> <!-- qv-wrapper --> 43 44 45<p> 46 M 開發人員預覽版導入新的應用程式權限模型,簡化使用者安裝和升級應用程式的程序。 47如果 M 預覽版上執行的應用程式支援新的權限模型,使用者安裝或升級應用程式時,不需要授與任何權限。應用程式會在需要時才要求權限,而且系統會對使用者顯示要求權限的對話方塊。 48 49 50 51 52</p> 53 54<p> 55 如果應用程式支援新的權限模型,它仍能在在執行舊版 Android 的裝置上安裝並執行 (在那些裝置上使用舊的權限模型)。 56 57 58</p> 59 60<h2 id="overview"> 61 總覽 62</h2> 63 64<p> 65 使用 M 開發人員預覽版,平台導入新的應用程式權限模型。 66以下是這個新模型的主要元件摘要: 67</p> 68 69<ul> 70 <li> 71 <strong>宣告權限:</strong>應用程式會在宣示說明中宣告所需的所有權限,如舊版 Android 平台。 72 73 </li> 74 75 <li> 76 <strong>權限群組:</strong>權限會根據其功能分為「權限群組」 77<em></em>。例如, 78<code>CONTACTS</code> 權限群組包含讀取和寫入使用者聯絡人與設定檔資訊的權限。 79 80 </li> 81 82 <li> 83 <p><strong>安裝期間授與的有限權限:</strong>當使用者安裝或更新應用程式時,系統會將應用程式所要求且歸入 {@link 84android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} 的所有權限授與應用程式。 85 86 87 例如,會在安裝期間自動授與歸入 {@link 88android.content.pm.PermissionInfo#PROTECTION_NORMAL PROTECTION_NORMAL} 的鬧鐘與網際網路權限。 89 90 </p> 91 92 <p>系統也會授與應用程式簽名和系統權限,如<a href="#system-apps">系統應用程式和簽名</a>所述。 93 94安裝期間「不」<em></em>會提示使用者授與任何權限。 95</p> 96 </li> 97 98 <li> 99 <strong>使用者在執行階段授與權限:</strong>應用程式要求權限時,系統會對使用者顯示對話方塊,接著呼叫應用程式的回呼函數,通知它是否已授與權限。 100 101如果使用者授與權限,應用程式會獲得在應用程式宣示說明中所宣告之權限功能區域中的所有權限。 102 103 104 </li> 105 106</ul> 107 108<p> 109 此權限模型改變應用程式要求權限的功能行為。 110以下是您應遵循以調整此模型的開發做法摘要: 111 112</p> 113 114<ul> 115 116 <li> 117 <strong>一律檢查是否具備權限:</strong>當應用程式需要執行任何需要權限的動作時,都應要先檢查是否具備有該權限。 118 119若不具備,即要求獲得授與該權限。 120 121 </li> 122 123 <li> 124 <strong>適當處理缺少權限的情況:</strong>如果應用程式未獲授與適當的權限,它應要能完全處理失敗。 125 126 例如,若只有新增功能需要該權限,應用程式可以將該功能停用。 127如果應用程式務必要具備該權限才能運作,應用程式可以停用其所有功能,並通知使用者務必要授與該權限。 128 129 130 </li> 131 132 <div class="figure" style="width:220px" id="fig-perms-screen"> 133 <img src="{@docRoot}preview/features/images/app-permissions-screen_2x.png" srcset="{@docRoot}preview/features/images/app-permissions-screen.png 1x, {@docRoot}preview/features/images/app-permissions-screen_2x.png 2x" alt="" width="220"> 134 <p class="img-caption"> 135 <strong>圖 1.</strong>應用程式 [設定] 的權限畫面。 136 </p> 137 </div> 138 139 <li> 140 <strong>權限可以撤銷:</strong>使用者可以隨時撤銷應用程式的權限。 141如果使用者關閉應用程式的權限,並「不」<em></em>會通知應用程式。 142再次強調,您的應用程式在執行任何受限制的動作之前,應該驗證它是否具備所需的權限。 143 144 </li> 145</ul> 146 147<p class="note"> 148 <strong>注意:</strong>如果應用程式是以 M 開發人員預覽版為目標,「務必要」 149<em></em>使用新的權限模型。 150</p> 151 152<p> 153 自 M 開發人員預覽版推出起,並非所有 Google 應用程式都完全實作新的權限模型。 154Google 正透過 M 開發人員預覽版逐漸更新這些應用程式,以適當保留權限切換設定。 155 156 157</p> 158 159<p class="note"> 160 <strong>注意:</strong>如果您的應用程式有自己的 API 介面,務必要先確定呼叫端具備存取該資料的必要權限後,再 Proxy 權限。 161 162 163</p> 164 165<h3 id="system-apps"> 166 系統應用程式和簽名權限 167</h3> 168 169<p> 170 一般來說,當使用者安裝應用程式時,系統只會將 171 {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL 172 PROTECTION_NORMAL} 授與應用程式。不過,在某些情況下,系統會授與應用程式更多權限: 173 174</p> 175 176<ul> 177 <li>如果應用程式屬於系統映像的一部分,會自動獲授與其宣示說明中列出的所有權限。 178 179 </li> 180 181 <li>如果應用程式要求宣示說明中歸入 {@link 182android.content.pm.PermissionInfo#PROTECTION_SIGNATURE PROTECTION_SIGNATURE} 的權限,並和宣告那些權限的應用程式一樣,以相同的憑證簽署應用程式,系統會在安裝時將那些權限授與要求的應用程式。 183 184 185 186 </li> 187</ul> 188 189<p> 190 在這兩種情況下,使用者仍能隨時撤銷權限,只要前往系統的 [設定]<strong></strong> 畫面,然後選擇 [應用程式] ><strong></strong> 191 192 <i>app_name</i> > [權限]<strong></strong>。應用程式應持續在執行階段檢查是否具備權限,並在必要時予以要求。 193 194 195</p> 196 197<h3 id="compatibility"> 198 往後和回溯相容性 199</h3> 200 201<p> 202 如果應用程式不是以 M 開發人員預覽版為目標,即使在 M 預覽版裝置上,應用程式也會持續使用舊的權限模型。 203當使用者安裝應用程式時,系統會要求使用者授與應用程式的宣示說明中列出的所有權現。 204 205 206</p> 207 208<p class="note"> 209 <strong>注意:</strong>在執行 M 開發人員預覽版的裝置上,使用者能從應用程式的設定畫面關閉任何應用程式 (包括舊版應用程式) 的權限。 210 211如果使用者關閉舊版應用程式的權限,系統會自動停用適當功能。 212當應用程式嘗試執行需要那項權限的操作時,該操作不一定會造成例外狀況。 213 214而可能傳回空的資料集,通知發生錯誤,或展示未預期的行為。 215例如,如果您不具備查詢行事曆的權限,方法會傳回空的資料集。 216 217</p> 218 219<p> 220 如果您在並非執行 M 預覽版的裝置上使用新的權限模型來安裝應用程式,系統會將它和任何其他應用程式一視同仁:系統會在安裝期間要求使用者授與所有宣告的權限。 221 222 223 224</p> 225 226<p class="note"> 227 <strong>注意:</strong>對於預覽版,您必須將 SDK 最低版本設定為 M 預覽版 SDK,才能以預覽版 SDK 編譯。 228這表示在開發人員預覽版期間,您將無法在舊版平台上測試這類應用程式。 229 230 231</p> 232 233<h3 id="perms-vs-intents">權限與意圖比較</h3> 234 235<p> 236 在許多情況下,您可以為應用程式在兩種方法當中擇一來執行工作。 237您可以讓應用程式要求權限以自行執行操作。 238或者,您可以讓應用程式使用意圖,讓其他應用程式來執行工作。 239 240</p> 241 242<p> 243 例如,假設您的應用程式需要能夠使用裝置相機拍攝相片。 244您的應用程式能要求 245<code>android.permission.CAMERA</code> 權限,讓應用程式直接存取相機。 246接著,應用程式會使用相機 API 來控制相機並拍攝相片。 247這種方法可讓您的應用程式對攝影處理程序有完整控制權,並讓您將相機 UI 納入應用程式。 248 249 250</p> 251 252<p> 253 不過,如果您不需要這類控制權,您可以只使用 {@link 254android.provider.MediaStore#ACTION_IMAGE_CAPTURE ACTION_IMAGE_CAPTURE} 意圖來要求影像。 255當您啟動意圖時,會提示使用者選擇相機應用程式 (如果還沒有預設的相機應用程式),然後該應用程式會拍攝相片。 256 257相機應用程式會將相片傳回應用程式的 {@link 258 android.app.Activity#onActivityResult onActivityResult()} 方法。 259</p> 260 261<p> 262 同樣地,如果您需要撥打電話、存取使用者的聯絡人等等,您都可以建立適當的意圖來執行,或是要求權限,然後直接存取適當的物件。 263 264每種方法各有利弊。 265 266</p> 267 268<p> 269 如果您使用權限: 270</p> 271 272<ul> 273 <li>當您執行操作時,應用程式對使用者體驗有完整控制權。 274不過,如此多樣化控制使您必須設計適當的 UI,而增加工作複雜度。 275 276 </li> 277 278 <li>當您初次執行操作時,會提示使用者授與權限 (僅此一次)。 279之後應用程式可以逕行執行該操作,不需要再與使用者有其他互動。 280不過,如果使用者未授與權限 (或稍後予以撤銷),您的應用程式會完全無法執行該操作。 281 282 283 </li> 284</ul> 285 286<p> 287 如果您使用意圖: 288</p> 289 290<ul> 291 <li>您不必為該操作設計 UI。處理意圖的應用程式會提供 UI。不過,這表示您對使用者體驗沒有控制權。 292 293使用者可能會和您不曾見過的應用程式互動。 294 295 </li> 296 297 <li>如果使用者沒有執行該操作的預設應用程式,系統會提示使用者選擇應用程式。如果使用者未指定預設處理常式,每次執行操作時可能都要完成額外的對話方塊。 298 299 300 301 </li> 302</ul> 303 304<h2 id="coding">編寫執行階段權限的程式碼</h2> 305 306<p> 307 如果您的應用程式是以新的 M 開發人員預覽版為目標,請務必使用新的權限模型。 308這表示除了在宣示說明中宣告所需的權限之外,您也必須在執行階段檢查是否具備權限,並在您不具備時要求權限。 309 310 311 312</p> 313 314<h3 id="enabling"> 315 啟用新的權限模型 316</h3> 317 318<p> 319 如要啟用新的 M 開發人員預覽版權限模型,可將應用程式的 320<code>targetSdkVersion</code> 屬性設定為 <code>"MNC"</code>,並將 321<code>compileSdkVersion</code> 設定為 <code>"android-MNC"</code>。這樣做可啟用所有新權限功能。 322 323</p> 324 325<p> 326 對於預覽版,您必須將 <code>minSdkVersion</code> 設定為 327<code>"MNC"</code>,才能以預覽版 SDK 編譯。 328</p> 329 330<h3 id="m-only-perm"> 331 指定只限 M 預覽版使用的權限 332</h3> 333 334<p> 335 您可以在宣示說明中使用新的 <code><uses-permission-sdk-m></code> 元素,指出只有在 M 預覽版上才需要某權限。 336如果您以這種方式宣告權限,每當在舊版裝置上安裝應用程式時,系統都不會提示使用者或將權限授與應用程式。藉由使用 <code><uses-permission-sdk-m></code> 元素,當使用者安裝更新時,您不需要強制他們授與權限,就可以將新的權限新增至更新的應用程式版本。 337 338 339 340 341 342 343</p> 344 345<p> 346 如果應用程式在使用 M 開發人員預覽版的裝置上執行, 347<code><uses-permission-sdk-m></code> 的運作方式會和 348<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> 相同。 349 當他們安裝應用程式時,系統不會提示使用者授與任何權限,而應用程式會在需要時才要求權限。 350 351</p> 352 353<h3 id="prompting"> 354 提示授與權限 355</h3> 356 357<p> 358 如果您的應用程式使用新的 M 開發人員預覽版權限模型,在執行 M 預覽版的裝置上初次啟動應用程式時,不會要求使用者授與所有權限。 359 360您的應用程式會在需要時才要求權限。 361應用程式要求權限時,系統會對使用者顯示對話方塊。 362 363</p> 364 365<p> 366 如果您的應用程式在 SDK 22 以下版本的裝置上執行,應用程式會使用舊的權限模型。 367當使用者安裝應用程式時,會提示他們授與應用程式在其宣示說明中要求的所有權限,但標示為 <code><uses-permission-sdk-m></code> 的那些權限除外。 368 369 370</p> 371 372<h4 id="check-platform">檢查應用程式執行所在的平台</h4> 373 374<p> 375 只有執行 M 開發人員預覽版的裝置上才支援此權限模型。 376呼叫這些方法之前,應用程式應該檢查 {@link android.os.Build.VERSION#CODENAME 377 Build.VERSION.CODENAME} 的值,驗證它執行所在的平台。 378 379如果裝置是執行 M 開發人員預覽版, 380{@link android.os.Build.VERSION#CODENAME CODENAME} 是 <code>"MNC"</code>。 381</p> 382 383<h4 id="check-for-permission">檢查應用程式是否具備所需權限</h4> 384 385<p>當使用者嘗試執行需要權限的操作時,應用程式會檢查它目前是否具備可執行此操作的權限。 386如要這麼做,應用程式可呼叫 387 388<code>Context.checkSelfPermission(<i>permission_name</i>)</code>。由於使用者可以隨時撤銷應用程式的權限,即使應用程式知道使用者已授與該權限,還是應該執行此檢查。 389 390 391例如,如果使用者想要使用應用程式拍攝相片,應用程式會呼叫 <code>Context.checkSelfPermission(Manifest.permission.CAMERA)</code>。 392 393</p> 394 395<p class="table-caption" id="permission-groups"> 396 <strong>表 1.</strong>權限和權限群組。</p> 397<table> 398 <tr> 399 <th scope="col">權限群組</th> 400 <th scope="col">權限</th> 401 </tr> 402 403 <tr> 404 <td><code>android.permission-group.CALENDAR</code></td> 405 <td> 406 <ul> 407 <li> 408 <code>android.permission.READ_CALENDAR</code> 409 </li> 410 </ul> 411 <ul> 412 <li> 413 <code>android.permission.WRITE_CALENDAR</code> 414 </li> 415 </ul> 416 </td> 417 </tr> 418 419 <tr> 420 <td><code>android.permission-group.CAMERA</code></td> 421 <td> 422 <ul> 423 <li> 424 <code>android.permission.CAMERA</code> 425 </li> 426 </ul> 427 </td> 428 </tr> 429 430 <tr> 431 <td><code>android.permission-group.CONTACTS</code></td> 432 <td> 433 <ul> 434 <li> 435 <code>android.permission.READ_CONTACTS</code> 436 </li> 437 <li> 438 <code>android.permission.WRITE_CONTACTS</code> 439 </li> 440 <li> 441 <code>android.permission.READ_PROFILE</code> 442 </li> 443 <li> 444 <code>android.permission.WRITE_PROFILE</code> 445 </li> 446 </ul> 447 </td> 448 </tr> 449 450 <tr> 451 <td><code>android.permission-group.LOCATION</code></td> 452 <td> 453 <ul> 454 <li> 455 <code>android.permission.ACCESS_FINE_LOCATION</code> 456 </li> 457 <li> 458 <code>android.permission.ACCESS_COARSE_LOCATION</code> 459 </li> 460 </ul> 461 </td> 462 </tr> 463 464 <tr> 465 <td><code>android.permission-group.MICROPHONE</code></td> 466 <td> 467 <ul> 468 <li> 469 <code>android.permission.RECORD_AUDIO</code> 470 </li> 471 </ul> 472 </td> 473 </tr> 474 475 <tr> 476 <td><code>android.permission-group.PHONE</code></td> 477 <td> 478 <ul> 479 <li> 480 <code>android.permission.READ_PHONE_STATE</code> 481 </li> 482 <li> 483 <code>android.permission.CALL_PHONE</code> 484 </li> 485 <li> 486 <code>android.permission.READ_CALL_LOG</code> 487 </li> 488 <li> 489 <code>android.permission.WRITE_CALL_LOG</code> 490 </li> 491 <li> 492 <code>com.android.voicemail.permission.ADD_VOICEMAIL</code> 493 </li> 494 <li> 495 <code>android.permission.USE_SIP</code> 496 </li> 497 <li> 498 <code>android.permission.PROCESS_OUTGOING_CALLS</code> 499 </li> 500 </ul> 501 </td> 502 </tr> 503 504 <tr> 505 <td><code>android.permission-group.SENSORS</code></td> 506 <td> 507 <ul> 508 <li> 509 <code>android.permission.BODY_SENSORS</code> 510 </li> 511 </ul> 512 <ul> 513 <li> 514 <code>android.permission.USE_FINGERPRINT</code> 515 </li> 516 </ul> 517 </td> 518 </tr> 519 520 <tr> 521 <td><code>android.permission-group.SMS</code></td> 522 <td> 523 <ul> 524 <li> 525 <code>android.permission.SEND_SMS</code> 526 </li> 527 <li> 528 <code>android.permission.RECEIVE_SMS</code> 529 </li> 530 <li> 531 <code>android.permission.READ_SMS</code> 532 </li> 533 <li> 534 <code>android.permission.RECEIVE_WAP_PUSH</code> 535 </li> 536 <li> 537 <code>android.permission.RECEIVE_MMS</code> 538 </li> 539 <li> 540 <code>android.permission.READ_CELL_BROADCASTS</code> 541 </li> 542 </ul> 543 </td> 544 </tr> 545 546</table> 547 548<h4 id="request-permissions">必要時要求權限</h4> 549 550<p>如果應用程式還沒有所需的權限,應用程式會呼叫 551<code>Activity.requestPermissions(String[], int)</code> 方法以要求適當的權限。 552應用程式會傳遞它所需的權限,還有整數「要求代碼」。 553 554 這種方法以非同步方式運作:它會立即傳回,並在使用者回應對話方塊後,系統會以該結果呼叫應用程式的回呼方法,傳遞應用程式傳遞給 <code>requestPermissions()</code> 的相同「要求代碼」。 555 556 557</p> 558 559 <p>下列程式碼會檢查應用程式是否具備讀取使用者聯絡人的權限,並在必要時要求權限。 560</p> 561 562<pre> 563if (checkSelfPermission(Manifest.permission.READ_CONTACTS) 564 != PackageManager.PERMISSION_GRANTED) { 565 requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 566 MY_PERMISSIONS_REQUEST_READ_CONTACTS); 567 568 // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an 569 // app-defined int constant 570 571 return; 572} 573</pre> 574 575<h4 id="handle-response">處理權限要求回應</h4> 576 577<p> 578 當應用程式要求權限時,系統會對使用者呈現對話方塊。 579當使用者回應時,系統會呼叫 <code>Activity.onRequestPermissionsResult(int, String[], int[])</code> 並將使用者回應傳遞給它。 580 581您的應用程式需要覆寫該方法。將您傳遞給 <code>requestPermissions()</code> 的相同要求代碼傳遞給回呼。 582 583例如,如果應用程式要求 <code>READ_CONTACTS</code> 存取權,可能會有下列回呼方法: 584 585 586</p> 587 588<pre> 589@Override 590public void onRequestPermissionsResult(int requestCode, 591 String permissions[], int[] grantResults) { 592 switch (requestCode) { 593 case MY_PERMISSIONS_REQUEST_READ_CONTACTS: { 594 if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 595 596 // permission was granted, yay! do the 597 // calendar task you need to do. 598 599 } else { 600 601 // permission denied, boo! Disable the 602 // functionality that depends on this permission. 603 } 604 return; 605 } 606 607 // other 'switch' lines to check for other 608 // permissions this app might request 609 } 610} 611</pre> 612 613 <p>如果使用者授與權限,系統就會將應用程式宣示說明所列出該功能區域的所有權限給予應用程式。 614如果使用者拒絕要求,您應該執行適當動作。 615例如,您可能會停用依存於此權限的任何選單動作。 616 617 </li> 618</p> 619 620<p> 621 系統要求使用者授與權限時,使用者可選擇告知系統不要再次要求該權限。 622在上述情況下,當應用程式使用 <code>requestPermissions()</code> 要求該權限時,系統會立即拒絕要求。 623 624在這種情況下,如果使用者再次明確拒絕您的要求,系統會以相同的方式呼叫您的 <code>onRequestPermissionsResult()</code>。 625 626基於這個理由,您的應用程式不能假設已與使用者發生任何直接互動。 627 628</p> 629 630<h2 id="testing">測試執行階段權限</h2> 631 632 633<p> 634 如果您的應用程式是以新的 M 開發人員預覽版為目標,您必須測試它是否能適當處理權限。 635您不能假設應用程式在執行時具備任何特定權限。 636應用程式初次啟動時,很可能不具備任何權限,且使用者可隨時撤銷或還原權限。 637 638 639</p> 640 641<p> 642 您應該測試應用程式,確保它在所有權限情況下都能正常運作。 643使用 M 預覽版 SDK,我們現在提供 <a href="{@docRoot}tools/help/adb.html">Android 偵錯橋 (adb)</a> 命令,不管需要嘗試哪種權限設定都能讓您測試。 644 645 646 647</p> 648 649<h3> 650 新的 adb 命令和選項 651</h3> 652 653<p> 654 M 預覽版 SDK 平台工具提供的數個命令可讓您測試應用程式如何處理權限。 655 656</p> 657 658<h4> 659 連同權限一併安裝 660</h4> 661 662<p> 663 您可以使用 <a href="{@docRoot}tools/help/adb.html#move"><code>adb 664 install</code></a> 命令的新 <code>-g</code> 選項,安裝應用程式並授與其宣示說明中列出的所有權限: 665 666</p> 667 668<pre class="no-pretty-print"> 669$ adb install -g <path_to_apk> 670</pre> 671 672<h4> 673 授與和撤銷權限 674</h4> 675 676<p> 677 您可以使用新的 ADB <a href="{@docRoot}tools/help/adb.html#pm">套件管理員 (pm)</a> 命令,對安裝的應用程式授與和撤銷權限。此功能在自動化測試時非常實用。 678 679 680</p> 681 682<p> 683 如要授與權限,可使用套件管理員的 <code>grant</code> 命令: 684</p> 685 686<pre class="no-pretty-print"> 687$ adb pm grant <package_name> <permission_name> 688</pre> 689 690<p> 691 例如,如要將可錄製音訊的權限授與 com.example.myapp 套件,請使用此命令: 692 693</p> 694 695<pre class="no-pretty-print"> 696$ adb pm grant com.example.myapp android.permission.RECORD_AUDIO 697</pre> 698 699<p> 700 如要撤銷權限,可使用套件管理員的 <code>revoke</code> 命令: 701</p> 702 703<pre class="no-pretty-print"> 704$ adb pm revoke <package_name> <permission_name> 705</pre> 706 707<h2 id="best-practices">最佳做法</h2> 708 709<p> 710 新的權限模型讓使用者有更順暢的體驗,並能輕鬆安裝應用程式且對應用程式執行的工作感到自在。 711 712建議使用下列最佳做法以充分利用新的模型。 713 714</p> 715 716 717<h3 id="bp-what-you-need">只要求您所需的權限</h3> 718 719<p> 720 每次要求權限時,您都是在強迫使用者做出決定。 721 如果使用者拒絕要求,就會減少您應用程式的功能。 722 您應該儘可能減少提出這些要求的次數。 723</p> 724 725<p> 726 例如,您的應用程式可經常使用<a href="{@docRoot}guide/components/intents-filters.html">意圖</a>來取得所需功能,而不是要求權限。 727 728如果您的應用程式需要使用手機的相機拍攝相片,應用程式可以使用 {@link 729 android.provider.MediaStore#ACTION_IMAGE_CAPTURE 730 MediaStore.ACTION_IMAGE_CAPTURE} 意圖。 731當您的應用程式執行意圖時,系統會提示使用者選擇已安裝的相機應用程式來拍攝相片。 732 733 734</p> 735 736<h3 id="bp-dont-overwhelm"> 737 別讓使用者無法承受 738</h3> 739 740<p> 741 如果您讓使用者一次面對太多權限要求,可能會讓使用者無法承受而結束您的應用程式。您應該改為在需要時才要求權限。 742 743 744</p> 745 746<p> 747 在某些情況下,您的應用程式可能必須具備一或多個權限。在那種情況下,在應用程式啟動時立即要求所有權限是合理的舉措。 748 749例如,如果您建立攝影應用程式,該應用程式會需要存取裝置相機。 750使用者初次啟動應用程式時,看到要求使用相機的權限不會被嚇到。 751 752但如果相同的應用程式具有與使用者聯絡人分享相片的功能,您可能「不」<em></em>應該在初次啟動時要求該權限。 753 754可以等到使用者嘗試使用「分享」功能時,再要求該權限。 755 756</p> 757 758<p> 759 如果您的應用程式提供教學課程,在教學課程結束時要求應用程式的基本權限是合理的舉措。 760 761</p> 762 763<h3 id="bp-explain"> 764 說明需要權限的原因 765</h3> 766 767<p> 768 當您呼叫 769<code>requestPermissions()</code> 時,系統顯示的權限對話方塊會說明您的應用程式想要的權限,但不會說明原因。 770在某些情況下,使用者可能會感到不解。 771 在呼叫 <code>requestPermissions()</code> 前對使用者說明應用程式想要權限的原因是不錯的想法。 772 773</p> 774 775<p> 776 例如,攝影應用程式可能想要使用定位服務,以便將相片加上地理標籤。 777一般使用者可能不明白相片可以包含定位資訊,而不明白為何攝影應用程式會想要知道位置。 778 779在這種情況下,在呼叫 <code>requestPermissions()</code>「之前」<em></em>,將此功能的相關資訊告訴使用者會是不錯的想法。 780 781 782</p> 783 784<p> 785 您可以將這些要求與應用程式教學課程結合來完成此作業。教學課程可依序顯示應用程式的各項功能,並可以同時說明需要哪些權限。 786 787例如,攝影應用程式的教學課程可以示範「與聯絡人分享相片」功能,接著告訴使用者需要提供權限,應用程式才能看到使用者的聯絡人。 788 789 790接著,應用程式可以呼叫 <code>requestPermissions()</code>,要求使用者提供該存取權。 791當然,並非每位使用者都會依照教學課程執行動作,所以您仍需要在應用程式的正常操作期間檢查和要求權限。 792 793 794</p> 795