Skip to content

Commit 9824e54

Browse files
committed
認証機能のバグを直しました
1 parent 9f86100 commit 9824e54

File tree

5 files changed

+180
-50
lines changed

5 files changed

+180
-50
lines changed

Diff for: app/src/main/java/com/example/runningavater/MyAppNavHost.kt

+8-8
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fun MyAppNavHost(
6161
val startDestination = getStartDestination(context)
6262
Scaffold(
6363
bottomBar = {
64-
if (currentDestination?.route?.startsWith("initialFlow") != true) {
64+
if (currentDestination?.route?.startsWith("initialFlow") != true && currentDestination?.route?.startsWith("authentication") != true) {
6565
MainBottomBar(currentDestination, navController)
6666
}
6767
},
@@ -123,13 +123,13 @@ private fun MainBottomBar(
123123
}
124124
},
125125
colors =
126-
NavigationBarItemDefaults.colors(
127-
selectedIconColor = Color.White,
128-
selectedTextColor = Color.White,
129-
unselectedIconColor = Color.White.copy(alpha = 0.5f),
130-
unselectedTextColor = Color.White.copy(alpha = 0.5f),
131-
indicatorColor = Color.White.copy(alpha = 0.3f),
132-
),
126+
NavigationBarItemDefaults.colors(
127+
selectedIconColor = Color.White,
128+
selectedTextColor = Color.White,
129+
unselectedIconColor = Color.White.copy(alpha = 0.5f),
130+
unselectedTextColor = Color.White.copy(alpha = 0.5f),
131+
indicatorColor = Color.White.copy(alpha = 0.3f),
132+
),
133133
)
134134
}
135135
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.example.runningavater.authentication
2+
3+
import androidx.compose.material3.AlertDialog
4+
import androidx.compose.material3.Icon
5+
import androidx.compose.material3.Text
6+
import androidx.compose.material3.TextButton
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.ui.graphics.vector.ImageVector
9+
10+
@Composable
11+
fun AuthenticationErrorDialog(
12+
onDismissRequest: () -> Unit,
13+
onConfirmation: () -> Unit,
14+
dialogTitle: String,
15+
dialogText: String,
16+
icon: ImageVector,
17+
) {
18+
AlertDialog(
19+
icon = {
20+
Icon(icon, contentDescription = "Example Icon")
21+
},
22+
title = {
23+
Text(text = dialogTitle)
24+
},
25+
text = {
26+
Text(text = dialogText)
27+
},
28+
onDismissRequest = {
29+
onDismissRequest()
30+
},
31+
confirmButton = {
32+
TextButton(
33+
onClick = {
34+
onConfirmation()
35+
}
36+
) {
37+
Text("設定へ")
38+
}
39+
},
40+
)
41+
}

Diff for: app/src/main/java/com/example/runningavater/authentication/AuthenticationScreen.kt

+62-7
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,95 @@ import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
1010
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
1111
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
1212
import androidx.biometric.BiometricPrompt
13+
import androidx.compose.material.icons.Icons
14+
import androidx.compose.material.icons.filled.Info
1315
import androidx.compose.material3.CircularProgressIndicator
1416
import androidx.compose.runtime.Composable
15-
import androidx.compose.runtime.LaunchedEffect
17+
import androidx.compose.runtime.DisposableEffect
18+
import androidx.compose.runtime.mutableStateOf
19+
import androidx.compose.runtime.remember
1620
import androidx.compose.ui.Modifier
1721
import androidx.compose.ui.platform.LocalContext
22+
import androidx.compose.ui.platform.LocalLifecycleOwner
1823
import androidx.core.content.ContextCompat
1924
import androidx.fragment.app.FragmentActivity
25+
import androidx.lifecycle.Lifecycle
26+
import androidx.lifecycle.LifecycleEventObserver
2027
import androidx.navigation.NavController
2128

29+
@Composable
30+
fun LifecycleResumeEffect(onResume: () -> Unit) {
31+
// 現在の画面のLifecycleOwnerを取得
32+
val lifecycleOwner = LocalLifecycleOwner.current
33+
DisposableEffect(lifecycleOwner) {
34+
// LifecycleEventObserverでLifecycleのイベントを監視する
35+
val observer = LifecycleEventObserver { _, event ->
36+
if (event == Lifecycle.Event.ON_RESUME) {
37+
// onResumeになったときに呼び出される
38+
onResume()
39+
}
40+
}
41+
// 監視を開始
42+
lifecycleOwner.lifecycle.addObserver(observer)
43+
44+
// Composableが破棄されるときに呼び出される
45+
onDispose {
46+
lifecycleOwner.lifecycle.removeObserver(observer)
47+
}
48+
}
49+
}
50+
51+
2252
@Composable
2353
fun AuthenticationScreen(
2454
navController: NavController,
2555
modifier: Modifier = Modifier,
2656
) {
2757
val context = LocalContext.current
28-
LaunchedEffect(key1 = Unit) {
58+
val openAlertDialog = remember { mutableStateOf(false) }
59+
when {
60+
openAlertDialog.value -> {
61+
AuthenticationErrorDialog(
62+
onDismissRequest = { openAlertDialog.value = false },
63+
onConfirmation = {
64+
openAlertDialog.value = false
65+
println("Confirmation registered") // Add logic here to handle confirmation.
66+
},
67+
dialogTitle = "端末のパスワードを設定してください",
68+
dialogText = "本サービスは、端末のパスワードを設定していただくと利用可能になります。",
69+
icon = Icons.Default.Info
70+
)
71+
}
72+
}
73+
LifecycleResumeEffect {
2974
when (BiometricManager.from(context).canAuthenticate(BIOMETRIC_STRONG or BIOMETRIC_WEAK or DEVICE_CREDENTIAL)) {
3075
BiometricManager.BIOMETRIC_SUCCESS -> { // 生体認証が利用可能
3176
showAuthenticationDialog(context, navController)
3277
}
3378

79+
3480
BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> { // 生体情報が端末に登録されていない
3581
val enrollIntent =
3682
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
37-
Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
83+
val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
3884
putExtra(
3985
Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
40-
BIOMETRIC_STRONG or DEVICE_CREDENTIAL,
86+
BIOMETRIC_STRONG or DEVICE_CREDENTIAL
4187
)
4288
}
89+
context.startActivity(enrollIntent)
4390
} else {
44-
TODO("VERSION.SDK_INT < R")
91+
// Android 10 以下
92+
showToast(context, "端末のパスワードを設定してください")
93+
val securityIntent = Intent(Settings.ACTION_SECURITY_SETTINGS).apply {
94+
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
95+
}
96+
context.startActivity(securityIntent)
4597
}
46-
context.startActivity(enrollIntent)
4798
}
4899

49100
BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE, BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE -> { // 生体認証ハードウェアが利用不可
50-
TODO("ダイアログを表示")
101+
showToast(context, "お使いの端末は対応本サービスを利用できません。")
51102
}
52103

53104
else -> throw IllegalStateException("ここには入らないはず。")
@@ -56,6 +107,10 @@ fun AuthenticationScreen(
56107
CircularProgressIndicator()
57108
}
58109

110+
fun showToast(context: android.content.Context, message: String) {
111+
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
112+
}
113+
59114
fun showAuthenticationDialog(
60115
context: Context,
61116
navController: NavController,

Diff for: app/src/main/java/com/example/runningavater/settings/ProfileScreen.kt

+39-16
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import androidx.compose.foundation.layout.fillMaxSize
1212
import androidx.compose.foundation.layout.padding
1313
import androidx.compose.foundation.layout.size
1414
import androidx.compose.foundation.shape.CircleShape
15+
import androidx.compose.material.icons.Icons
16+
import androidx.compose.material.icons.filled.Info
17+
import androidx.compose.material3.Button
1518
import androidx.compose.material3.Text
1619
import androidx.compose.runtime.Composable
1720
import androidx.compose.runtime.getValue
@@ -30,6 +33,7 @@ import androidx.navigation.NavHostController
3033
import coil.compose.rememberAsyncImagePainter
3134
import coil.request.ImageRequest
3235
import com.example.runningavater.R
36+
import com.example.runningavater.authentication.AuthenticationErrorDialog
3337

3438
@Composable
3539
fun ProfileScreen(navController: NavHostController) {
@@ -45,6 +49,21 @@ fun ProfileScreen(
4549
profileImageUri: Uri?,
4650
onImageSelected: (Uri) -> Unit,
4751
) {
52+
val openAlertDialog = remember { mutableStateOf(false) }
53+
when {
54+
openAlertDialog.value -> {
55+
AuthenticationErrorDialog(
56+
onDismissRequest = { openAlertDialog.value = false },
57+
onConfirmation = {
58+
openAlertDialog.value = false
59+
println("Confirmation registered") // Add logic here to handle confirmation.
60+
},
61+
dialogTitle = "Alert dialog example",
62+
dialogText = "This is an example of an alert dialog with buttons.",
63+
icon = Icons.Default.Info
64+
)
65+
}
66+
}
4867
val launcher =
4968
rememberLauncherForActivityResult(
5069
contract = ActivityResultContracts.GetContent(),
@@ -56,31 +75,32 @@ fun ProfileScreen(
5675

5776
Column(
5877
modifier =
59-
Modifier
60-
.fillMaxSize()
61-
.padding(16.dp),
78+
Modifier
79+
.fillMaxSize()
80+
.padding(16.dp),
6281
horizontalAlignment = Alignment.CenterHorizontally,
6382
) {
6483
Box(
6584
modifier =
66-
Modifier
67-
.size(100.dp)
68-
.padding(8.dp)
69-
.clickable {
70-
launcher.launch("image/*")
71-
}.background(Color.Gray, shape = CircleShape),
85+
Modifier
86+
.size(100.dp)
87+
.padding(8.dp)
88+
.clickable {
89+
launcher.launch("image/*")
90+
}
91+
.background(Color.Gray, shape = CircleShape),
7292
contentAlignment = Alignment.Center,
7393
) {
7494
if (profileImageUri != null) {
7595
Image(
7696
painter =
77-
rememberAsyncImagePainter(
78-
model =
79-
ImageRequest
80-
.Builder(LocalContext.current)
81-
.data(profileImageUri)
82-
.build(),
83-
),
97+
rememberAsyncImagePainter(
98+
model =
99+
ImageRequest
100+
.Builder(LocalContext.current)
101+
.data(profileImageUri)
102+
.build(),
103+
),
84104
contentDescription = "Profile Image",
85105
modifier = Modifier.size(100.dp),
86106
)
@@ -98,5 +118,8 @@ fun ProfileScreen(
98118
fontWeight = FontWeight.Bold,
99119
modifier = Modifier.padding(top = 16.dp),
100120
)
121+
Button(
122+
onClick = { openAlertDialog.value = true }
123+
) { }
101124
}
102125
}

0 commit comments

Comments
 (0)