39 lines
1.5 KiB
Kotlin
39 lines
1.5 KiB
Kotlin
package com.example.jnicpp.bowling
|
|||
|
|
|
||
|
|
import android.Manifest
|
||
|
|
import android.content.Context
|
||
|
|
import android.content.pm.PackageManager
|
||
|
|
import android.os.Build
|
||
|
|
import androidx.core.content.ContextCompat
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Single source of truth for which runtime permissions this feature needs
|
||
|
|
* and whether they're currently granted. The actual request flow (which
|
||
|
|
* must be owned by an Activity/Fragment via ActivityResultContracts) lives
|
||
|
|
* in [BowlingCameraActivity]; this object just centralizes the "what" so
|
||
|
|
* both the manifest expectations and the request flow can't drift apart.
|
||
|
|
*/
|
||
|
|
object CameraPermissions {
|
||
|
|
|
||
|
|
val REQUIRED: Array<String> = buildList {
|
||
|
|
add(Manifest.permission.CAMERA)
|
||
|
|
add(Manifest.permission.RECORD_AUDIO)
|
||
|
|
// Scoped storage (API 29+) lets an app insert into MediaStore's
|
||
|
|
// shared Movies collection without this permission; below that, it's
|
||
|
|
// required to save the recorded video into the gallery.
|
||
|
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
|
||
|
|
add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||
|
|
}
|
||
|
|
}.toTypedArray()
|
||
|
|
|
||
|
|
fun allGranted(context: Context): Boolean =
|
||
|
|
REQUIRED.all { permission ->
|
||
|
|
ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||
|
|
}
|
||
|
|
|
||
|
|
fun missing(context: Context): List<String> =
|
||
|
|
REQUIRED.filter { permission ->
|
||
|
|
ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED
|
||
|
|
}
|
||
|
|
}
|