feat: Add permission request

This commit is contained in:
Myzel394 2023-08-05 21:56:11 +02:00
parent b5afcc80ac
commit 591352a604
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
5 changed files with 152 additions and 45 deletions

View File

@ -10,6 +10,7 @@ import kotlinx.serialization.json.decodeFromStream
@Serializable
data class AppSettings(
val audioRecorderSettings: AudioRecorderSettings = AudioRecorderSettings(),
val hasSeenOnboarding: Boolean = false,
val showAdvancedSettings: Boolean = false,
) {
fun setShowAdvancedSettings(showAdvancedSettings: Boolean): AppSettings {
@ -20,6 +21,10 @@ data class AppSettings(
return copy(audioRecorderSettings = audioRecorderSettings)
}
fun setHasSeenOnboarding(hasSeenOnboarding: Boolean): AppSettings {
return copy(hasSeenOnboarding = hasSeenOnboarding)
}
companion object {
fun getDefaultInstance(): AppSettings = AppSettings()
}

View File

@ -1,5 +1,6 @@
package app.myzel394.locationtest.ui.components.AudioRecorder.atoms
package app.myzel394.locationtest.ui.components.AudioRecorder.molecules
import android.Manifest
import android.content.ServiceConnection
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
@ -29,6 +30,8 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import app.myzel394.locationtest.services.RecorderService
import app.myzel394.locationtest.ui.BIG_PRIMARY_BUTTON_SIZE
import app.myzel394.locationtest.ui.components.AudioRecorder.atoms.AudioVisualizer
import app.myzel394.locationtest.ui.components.atoms.PermissionRequester
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog
import java.time.format.DateTimeFormatter
@ -51,32 +54,45 @@ fun StartRecording(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.weight(1f))
Button(
onClick = {
RecorderService.startService(context, connection)
},
modifier = Modifier
.semantics {
contentDescription = "Start recording"
}
.size(200.dp)
.clip(shape = CircleShape),
colors = ButtonDefaults.outlinedButtonColors(),
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
PermissionRequester(
permission = arrayOf(Manifest.permission.RECORD_AUDIO),
icon = {
Icon(
Icons.Default.Mic,
contentDescription = null,
modifier = Modifier
.size(80.dp),
)
Spacer(modifier = Modifier.height(ButtonDefaults.IconSpacing))
Text(
"Start Recording",
style = MaterialTheme.typography.titleSmall,
)
},
onPermissionAvailable = {
RecorderService.startService(context, connection)
},
) { trigger ->
Button(
onClick = {
trigger()
},
modifier = Modifier
.semantics {
contentDescription = "Start recording"
}
.size(200.dp)
.clip(shape = CircleShape),
colors = ButtonDefaults.outlinedButtonColors(),
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Icon(
Icons.Default.Mic,
contentDescription = null,
modifier = Modifier
.size(80.dp),
)
Spacer(modifier = Modifier.height(ButtonDefaults.IconSpacing))
Text(
"Start Recording",
style = MaterialTheme.typography.titleSmall,
)
}
}
}
if (service?.recordingStart != null)

View File

@ -0,0 +1,96 @@
package app.myzel394.locationtest.ui.components.atoms
import android.graphics.drawable.Icon
import androidx.compose.foundation.layout.Spacer
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.OpenInBrowser
import androidx.compose.material.icons.filled.OpenInNew
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.PermissionChecker
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import app.myzel394.locationtest.ui.utils.PermissionHelper
import app.myzel394.locationtest.ui.utils.openAppSystemSettings
import kotlinx.serialization.json.JsonNull.content
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun PermissionRequester(
permission: Array<String>,
icon: (@Composable () -> Unit)? = null,
onPermissionAvailable: () -> Unit,
content: @Composable (trigger: () -> Unit) -> Unit
) {
val context = LocalContext.current
var showPermissionDenied by remember { mutableStateOf(false) }
val callback = {
if (PermissionHelper.checkPermissions(context, permission)) {
onPermissionAvailable()
} else {
showPermissionDenied = true
}
}
if (showPermissionDenied) {
AlertDialog(
onDismissRequest = {
showPermissionDenied = false
},
icon = icon,
title = {
Text("Permission denied")
},
text = {
Text("Please grant the permission to continue. You will be redirected to the app settings to grant the permission there.")
},
confirmButton = {
Button(
onClick = {
showPermissionDenied = false
context.openAppSystemSettings()
}
) {
Icon(
Icons.Default.OpenInNew,
contentDescription = null,
modifier = Modifier.size(ButtonDefaults.IconSize),
)
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
Text("OK")
}
},
dismissButton = {
Button(
onClick = {
showPermissionDenied = false
},
colors = ButtonDefaults.textButtonColors(),
) {
Icon(
Icons.Default.Cancel,
contentDescription = null,
modifier = Modifier.size(ButtonDefaults.IconSize),
)
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
Text("Cancel")
}
}
)
}
content(callback)
}

View File

@ -1,49 +1,29 @@
package app.myzel394.locationtest.ui.screens
import android.Manifest
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.media.MediaPlayer
import android.os.IBinder
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Mic
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.navigation.NavController
import app.myzel394.locationtest.services.RecorderService
import app.myzel394.locationtest.ui.components.AudioRecorder.atoms.RecordingStatus
import app.myzel394.locationtest.ui.components.AudioRecorder.atoms.StartRecording
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.RecordingStatus
import app.myzel394.locationtest.ui.components.AudioRecorder.molecules.StartRecording
import app.myzel394.locationtest.ui.enums.Screen
import app.myzel394.locationtest.ui.utils.rememberFileSaverDialog

View File

@ -2,9 +2,19 @@ package app.myzel394.locationtest.ui.utils
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.provider.Settings
import androidx.core.app.ActivityCompat
fun Context.openAppSystemSettings() {
startActivity(Intent().apply {
action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
data = Uri.fromParts("package", packageName, null)
})
}
// From @Bnyro
object PermissionHelper {
fun checkPermissions(context: Context, permissions: Array<String>): Boolean {