以 Kotlin 格式新增應用程式的執行階段權限

1. 歡迎

簡介

應用程式權限可用於提供對應用程式沙箱以外的資料和功能的存取權。還能夠讓應用程式存取網際網路、裝置位置及相機等內容,增強應用程式功能。

若要使用這些功能,您必須要求使用者提供權限。本程式碼研究室會逐步引導您新增執行階段權限,以及檢查是否授予權限。

軟硬體需求

須知事項

課程內容

  • 如何在 Android 資訊清單中新增權限。
  • 如何要求權限。
  • 如何處理權限遭接受及遭拒的情況。
  • 如何確認是否已授予權限。

建構內容

您可以製作會要求相機權限的應用程式。您將導入應用程式的權限部分,而非相機部分。

2. 建立 Android Studio 專案

  1. 開始新的 Android Studio 專案。
  2. 選擇「Empty Activity」。

70e5de28256e3dcb.png

  1. 將專案命名為「Permissions Codelab」,並將語言設為 Kotlin。

f2948b584ca99c47.png

3. 設定代碼

  1. 將下列依附元件的最新版本加入應用程式層級 build.gradle 檔案中。這些方法可讓您按程式碼研究室的後續說明來使用 Activity 程式庫。
implementation "androidx.activity:activity-ktx:1.2.2"
implementation "androidx.fragment:fragment-ktx:1.3.2"
  1. 在 Android 區塊中將 viewBinding 建構選項設為 true,即可啟用 ViewBinding
android {
   ...
   buildFeatures {
       viewBinding true
   }
}
  1. 再按綠色鐵鎚按鈕即可開始建構。這項操作會產生名為 ActivityMainBinding 的繫結類別,供您稍後使用 ViewBinding

d4064454e5c50111.png

  1. 請前往 activity_main.xml 檔案,並將程式碼替換成上述程式碼。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/main_layout"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Request Permissions"
       android:onClick="onClickRequestPermission"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
  1. 將這些字串新增至 strings.xml 檔案。
<string name="app_name">Permissions Codelab</string>
<string name="permission_required">Camera access is required to display the camera preview.</string>
<string name="ok">OK</string>
<string name="permission_granted">Permission is granted. You can use the camera now.</string>
  1. MainActivity.ktonCreate() 方法上方,定義版面配置的變數和 ViewBinding
private lateinit var layout: View
private lateinit var binding: ActivityMainBinding
  1. 請將 onCreate() 方法中的程式碼替換成下方程式碼。這個程式碼會初始化繫結,建立代表視圖的 val 並將其設為繫結的根,然後將版面配置設為繫結的 mainLayout
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   binding = ActivityMainBinding.inflate(layoutInflater)
   val view = binding.root
   layout = binding.mainLayout
   setContentView(view)
}
  1. 在檔案底部的 MainActivity 類別底下,新增擴充功能函式,以便在程式碼研究室中顯示 Snackbars。
fun View.showSnackbar(
   view: View,
   msg: String,
   length: Int,
   actionMessage: CharSequence?,
   action: (View) -> Unit
) {
   val snackbar = Snackbar.make(view, msg, length)
   if (actionMessage != null) {
       snackbar.setAction(actionMessage) {
           action(this)
       }.show()
   } else {
       snackbar.show()
   }
}

4. 在資訊清單中新增權限

首先,您必須使用 <uses-permission> 標記在 Android manifest 中宣告您的權限。

您所要求的權限有時還需要其他要求。在此情況下,除非裝置設有相機,否則無法使用相機應用程式。因此您必須將 <uses-feature> 標記加入資訊清單。

  1. AndroidManifest.xml 檔案中,將相機權限新增至 <application> 標記上方。
<uses-permission android:name="android.permission.CAMERA" />

5. 建立權限啟動器

MainActivity.kt,請建立 val 呼叫 requestPermissionLauncher 並複製這段程式碼。在接下來的幾個重點中,我們會在這裡細分。

private val requestPermissionLauncher =
   registerForActivityResult(
       ActivityResultContracts.RequestPermission()
   ) { isGranted: Boolean ->
       if (isGranted) {
           Log.i("Permission: ", "Granted")
       } else {
           Log.i("Permission: ", "Denied")
       }
   }
private val requestPermissionLauncher =
   registerForActivityResult(
       ActivityResultContracts.RequestPermission())
  • 新增回呼來處理是否授予的情況。在此情況下,我們正在記錄結果。
{ isGranted: Boolean ->
       if (isGranted) {
           Log.i("Permission: ", "Granted")
       } else {
           Log.i("Permission: ", "Denied")
       }
}

6. 要求權限

  1. 建立名為 onClickRequestPermission(view: View) 的函式,並將這個程式碼複製到其中。在接下來的幾個項目符號中,我們會詳細分析內部實景。
fun onClickRequestPermission(view: View) {
   when {
       ContextCompat.checkSelfPermission(
           this,
           Manifest.permission.CAMERA
       ) == PackageManager.PERMISSION_GRANTED -> {
           layout.showSnackbar(
               view,
               getString(R.string.permission_granted),
               Snackbar.LENGTH_INDEFINITE,
               null
           ) {}
       }

       ActivityCompat.shouldShowRequestPermissionRationale(
           this,
           Manifest.permission.CAMERA
       ) -> {
           layout.showSnackbar(
               view,
               getString(R.string.permission_required),
               Snackbar.LENGTH_INDEFINITE,
               getString(R.string.ok)
           ) {
               requestPermissionLauncher.launch(
                   Manifest.permission.CAMERA
               )
           }
       }

       else -> {
           requestPermissionLauncher.launch(
               Manifest.permission.CAMERA
           )
       }
   }
}
  • 設定 when 陳述式來涵蓋以下三種情況:已獲得權限、應用程式是否應顯示要求權限原因,以及是否提出過要求。
when {
   ContextCompat.checkSelfPermission(
       this,
       Manifest.permission.CAMERA
   ) == PackageManager.PERMISSION_GRANTED -> {

   }

   ActivityCompat.shouldShowRequestPermissionRationale(
       this,
       Manifest.permission.CAMERA
   ) -> {

   }

   else -> {

   }
}
  • 如果應用程式授予權限,請顯示 Snackbar,並公告。
ContextCompat.checkSelfPermission(
   this,
   Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED -> {
   layout.showSnackbar(
       view,
       getString(R.string.permission_granted),
       Snackbar.LENGTH_INDEFINITE,
       null
   ) {}
}
  • 如果 shouldShowRequestPermissionRationale() 傳回 true,則顯示使用者介面,進一步說明該功能需要特定權限的原因,並讓使用者得以透過使用者介面接受/拒絕權限。

a25d8c6c1d5051d.png

ActivityCompat.shouldShowRequestPermissionRationale(
   this,
   Manifest.permission.CAMERA
) -> {
   layout.showSnackbar(
       view,
       getString(R.string.permission_required),
       Snackbar.LENGTH_INDEFINITE,
       getString(R.string.ok)
   ) {
       requestPermissionLauncher.launch(
           Manifest.permission.CAMERA
       )
   }
}
  • 否則請提出權限要求。
else -> {
   requestPermissionLauncher.launch(
       Manifest.permission.CAMERA
   )
}

7. 摘要

這樣就可以了!本程式碼研究室會說明如何新增執行階段權限,並可用於位置、網路、媒體等權限!

您可以查看最終 程式碼 並閱讀 說明文件