Android 權限

      在〈Android 權限〉中尚無留言

Android 的權限很煩人,而且會讓MainActivity.kt 變的複雜而難維護,所以精簡如下方式

AndroidManifest.xml

AndroidManifest.xml 指定要開通的權限,請設定如下藍色的部份

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-feature android:name="android.hardware.camera.any" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <application>
............ </application> </manifest>

todo

MainActivity.kt

指定要開通的權限後,還需在 Android 的 MainActivity 讓使用者選擇是否允許權限開通

package net.ddns.mahaljsp.camera
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import net.ddns.mahaljsp.camera.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    lateinit var permission:MainPermission
    lateinit var ui: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ui= ActivityMainBinding.inflate(layoutInflater)
        setContentView(ui.root)
        permission=MainPermission(this)
    }
    fun init(){

    }

    //底下一定要寫在 Activity 視窗中
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array,
        grantResults:IntArray) 
    {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        permission.onRequestPermissionsResult(this, requestCode)
    }
}

上述的

 permission=MainPermission()

會開始進行權限詢問,詢問結果回到 MainAcitvy 的 onRequestPermissionResult() 方法。請注意 onRequestPermissionResult() 一定要寫在 MainActivity 類別中。這方法則又調用 MainPermission 裏的 result,這是為了不要讓 MainActivity 太複雜。

MainPermission.kt

MainPermission.kt 的完整代碼如下 。

package net.ddns.mahaljsp.camera

import android.Manifest
import android.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.content.pm.PackageManager
import android.os.Build
import android.view.WindowInsets
import android.view.WindowInsetsController
import android.view.WindowManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class MainPermission(context: Context) {
    val REQUEST_CODE = 10
    val REQUIRED_PERMISSIONS = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.CAMERA,
        Manifest.permission.RECORD_AUDIO,
    )
    fun allPermissionsGranted(context: Context) = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
    }
    init{
        //視窗最大化
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            var controller: WindowInsetsController? = (context as MainActivity).window.insetsController
            controller?.hide(WindowInsets.Type.statusBars())
        } else {
            @Suppress("DEPRECATION")
            (context as MainActivity).window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
            )

        }

        //取得權限
        if(!allPermissionsGranted(context)){
            ActivityCompat.requestPermissions(context as MainActivity,
                REQUIRED_PERMISSIONS,
                REQUEST_CODE
            )
        }
        else{
            (context as MainActivity).init()
        }
    }
    fun onRequestPermissionsResult(context: Context,requestCode:Int, ){
        if (requestCode== REQUEST_CODE) {
            if(!allPermissionsGranted(context)){
                val dialog= AlertDialog.Builder(context)
                dialog
                    .setTitle("旅遊記")
                    .setMessage("因您拒絕授權手機相關權限\n本程式無法提供AI派工服務\n\n若您真有需求, 請移除本程式, 並重新安裝")
                    .setPositiveButton("離開", DialogInterface.OnClickListener{ _, _->
                        (context as MainActivity).finish()
                    })
                    .show()
            }
            else{
                (context as MainActivity).init()
            }
        }
    }
}

todo

為什麼要經過這二層

為什麼 AndroidManiFest.xml 要指定一次權限,而 MainActivity.kt 又要詢問一次? 非得經過這二層嗎?? 是的,非得這樣不可,因為 AndroidManiFest.xml 是為了讓 Google Play 商店辨識用的,而代碼的部份是讓使用者選擇是否打開權限。

todo

todo

其它相關事項

todo

todo

todo

AndroidManifest.xml

todo

todo

todo

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *