mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
feat: Improve permission request
This commit is contained in:
parent
3f124a24e9
commit
1c49ac35b8
@ -69,13 +69,8 @@ fun StartRecording(
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
PermissionRequester(
|
||||
permission = arrayOf(Manifest.permission.RECORD_AUDIO),
|
||||
icon = {
|
||||
Icon(
|
||||
Icons.Default.Mic,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
permission = Manifest.permission.RECORD_AUDIO,
|
||||
icon = Icons.Default.Mic,
|
||||
onPermissionAvailable = {
|
||||
RecorderService.startService(context, connection)
|
||||
},
|
||||
|
@ -37,7 +37,7 @@ fun MessageBox(
|
||||
}
|
||||
val onContainerColor = when(type) {
|
||||
MessageType.ERROR -> MaterialTheme.colorScheme.onError
|
||||
MessageType.INFO -> MaterialTheme.colorScheme.onTertiary
|
||||
MessageType.INFO -> MaterialTheme.colorScheme.onTertiaryContainer
|
||||
MessageType.SUCCESS -> Color.Green
|
||||
MessageType.WARNING -> Color.Yellow
|
||||
}
|
||||
|
@ -1,10 +1,17 @@
|
||||
package app.myzel394.alibi.ui.components.atoms
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Cancel
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.OpenInNew
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
@ -12,55 +19,136 @@ import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.app.ActivityCompat
|
||||
import app.myzel394.alibi.R
|
||||
import app.myzel394.alibi.ui.utils.PermissionHelper
|
||||
import app.myzel394.alibi.ui.utils.openAppSystemSettings
|
||||
|
||||
@Composable
|
||||
fun PermissionRequester(
|
||||
permission: Array<String>,
|
||||
icon: (@Composable () -> Unit)? = null,
|
||||
permission: String,
|
||||
icon: ImageVector,
|
||||
onPermissionAvailable: () -> Unit,
|
||||
content: @Composable (trigger: () -> Unit) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
var showExplanationDialog by remember { mutableStateOf(false) }
|
||||
var isGranted by remember { mutableStateOf(PermissionHelper.hasGranted(context, permission)) }
|
||||
var visibleDialog by remember { mutableStateOf<VisibleDialog?>(null) }
|
||||
val requestPermission = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.RequestPermission(),
|
||||
onResult = { isPermissionGranted: Boolean ->
|
||||
isGranted = isPermissionGranted
|
||||
|
||||
if (isGranted) {
|
||||
onPermissionAvailable()
|
||||
} else {
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(context as Activity, permission)) {
|
||||
visibleDialog = VisibleDialog.REQUEST
|
||||
} else {
|
||||
visibleDialog = VisibleDialog.PERMANENTLY_DENIED
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
fun callback() {
|
||||
if (PermissionHelper.hasPermanentlyDenied(context, permission)) {
|
||||
showExplanationDialog = true
|
||||
return
|
||||
}
|
||||
|
||||
if (PermissionHelper.checkPermissions(context, permission)) {
|
||||
if (isGranted) {
|
||||
onPermissionAvailable()
|
||||
} else {
|
||||
requestPermission.launch(permission)
|
||||
}
|
||||
}
|
||||
|
||||
if (showExplanationDialog) {
|
||||
if (visibleDialog == VisibleDialog.REQUEST) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
showExplanationDialog = false
|
||||
visibleDialog = null
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
icon,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
icon = icon,
|
||||
title = {
|
||||
Text(stringResource(R.string.ui_permissions_request_title))
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.ui_permissions_request_message))
|
||||
Text(stringResource(R.string.ui_permissions_request))
|
||||
},
|
||||
confirmButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
showExplanationDialog = false
|
||||
visibleDialog = null
|
||||
callback()
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Check,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||
Text(stringResource(R.string.dialog_close_neutral_label))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
visibleDialog = null
|
||||
},
|
||||
colors = ButtonDefaults.textButtonColors(),
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Cancel,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(ButtonDefaults.IconSize),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
|
||||
Text(stringResource(R.string.dialog_close_cancel_label))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
if (visibleDialog == VisibleDialog.PERMANENTLY_DENIED) {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
visibleDialog = null
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
icon,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(stringResource(R.string.ui_permissions_request_title))
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Text(stringResource(R.string.ui_permissions_request))
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
MessageBox(
|
||||
type = MessageType.INFO,
|
||||
message = stringResource(R.string.ui_permissions_permanentlyDenied_message)
|
||||
)
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
visibleDialog = null
|
||||
context.openAppSystemSettings()
|
||||
}
|
||||
) {
|
||||
@ -76,7 +164,7 @@ fun PermissionRequester(
|
||||
dismissButton = {
|
||||
Button(
|
||||
onClick = {
|
||||
showExplanationDialog = false
|
||||
visibleDialog = null
|
||||
},
|
||||
colors = ButtonDefaults.textButtonColors(),
|
||||
) {
|
||||
@ -92,4 +180,9 @@ fun PermissionRequester(
|
||||
)
|
||||
}
|
||||
content(::callback)
|
||||
}
|
||||
|
||||
enum class VisibleDialog {
|
||||
REQUEST,
|
||||
PERMANENTLY_DENIED
|
||||
}
|
@ -10,34 +10,20 @@ import androidx.core.app.ActivityCompat
|
||||
|
||||
// From @Bnyro
|
||||
object PermissionHelper {
|
||||
fun checkPermissions(context: Context, permissions: Array<String>): Boolean {
|
||||
permissions.forEach {
|
||||
if (!hasGranted(context, it)) {
|
||||
ActivityCompat.requestPermissions(
|
||||
context as Activity,
|
||||
arrayOf(it),
|
||||
1
|
||||
)
|
||||
return false
|
||||
}
|
||||
fun checkPermission(context: Context, permission: String): Boolean {
|
||||
if (!hasGranted(context, permission)) {
|
||||
ActivityCompat.requestPermissions(
|
||||
context as Activity,
|
||||
arrayOf(permission),
|
||||
1
|
||||
)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun hasGranted(context: Context, permission: String): Boolean =
|
||||
ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||||
|
||||
fun hasPermanentlyDenied(context: Context, permission: String): Boolean =
|
||||
!hasGranted(context, permission) &&
|
||||
!ActivityCompat.shouldShowRequestPermissionRationale(context as Activity, permission)
|
||||
|
||||
fun hasPermanentlyDenied(context: Context, permission: Array<String>): Boolean {
|
||||
permission.forEach {
|
||||
if (hasPermanentlyDenied(context, it))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.openAppSystemSettings() {
|
||||
|
@ -15,7 +15,8 @@
|
||||
<string name="notificationChannels_recorder_description">Shows the current recording status</string>
|
||||
|
||||
<string name="ui_permissions_request_title">Permission denied</string>
|
||||
<string name="ui_permissions_request_message">Please grant the permission to continue. You will be redirected to the app settings to grant the permission there.</string>
|
||||
<string name="ui_permissions_request">Please grant the permission to continue</string>
|
||||
<string name="ui_permissions_permanentlyDenied_message">You will be redirected to the app settings to grant the permission there.</string>
|
||||
|
||||
<string name="ui_audioRecorder_action_start_label">Start Recording</string>
|
||||
<string name="ui_audioRecorder_action_saveOldRecording_label">Save Recording from <xliff:g name="date">%s</xliff:g></string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user