private fun createInitialProfile(
firebaseUser: FirebaseUser,
userId: String
): Map<String, Any?> {
val now = Timestamp.now()
return mapOf(
"id" to userId,
"nickname" to generateRandomNickname(),
"email" to (firebaseUser.email ?: ""),
"role" to "USER",
"gender" to null,
"lastLoginDate" to now,
"notificationEnabled" to true,
"marketingConsentEnabled" to null,
"privacyPolicyEnabled" to null,
"termsOfServiceEnabled" to null,
"lastSyncDate" to null,
"isAccountDeleted" to false,
"createdDate" to now,
"modifiedDate" to now,
)
}
-----------------------------------------------------------------
// 수정 전
private fun convertMapToJson(map: Map<String, Any?>): String {
val gson = Gson()
return gson.toJson(map)
}
// 수정 후
private fun convertMapToJson(map: Map<String, Any?>): String {
val gson = GsonBuilder()
.serializeNulls()
.create()
return gson.toJson(map)
}
map이 JSON으로 변환될 때, 값을 null로 넣은 쌍은 모두 제거되는 문제가 발생했다.
나는 값이 null인 쌍들도 모두 JSON으로 포함하고 싶었다.
이 문제는 serializeNulls()
로 null을 허용해주면 간단하게 해결된다.
@Composable
fun View(
url: String,
sharedSignInViewModel: SharedSignInViewModel = hiltViewModel()
) {
val context = LocalContext.current
Text(
text = "보기",
modifier = Modifier.clickable {
sharedSignInViewModel.openUrl(context, url)
},
style = TextStyle(
fontSize = 14.sp,
fontFamily = FontFamily(Font(R.font.inter_24pt_regular)),
color = Color(0xFFB3B3B3),
textDecoration = TextDecoration.Underline,
)
)
}
@Composable
fun MarketingConsent() {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(12.dp)
) {
Image(
painter = painterResource(id = R.drawable.check_without_circle),
contentDescription = "check_without_circle",
contentScale = ContentScale.Crop
)
Text(
text = stringResource(id = R.string.marketing_consent),
style =
TextStyle(
fontSize = 16.sp,
fontFamily = FontFamily(Font(R.font.inter_24pt_regular)),
fontWeight = FontWeight(500),
color = GrayScaleWhite,
)
)
View(url = stringResource(id = R.string.marketing_consent_url))
}
}
--------------------------------------
// 뷰모델
fun openUrl(context: Context, url: String) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
Intent
는 Android 시스템에서 컴포넌트 간의 통신을 관리하는 주요 객체이다. 다음과 같은 두 가지 주요 용도로 사용된다.
Activity 간의 이동
작업 요청
명시적(Intent Explicit)
val intent = Intent(this, TargetActivity::class.java)
startActivity(intent)
암시적(Intent Implicit)
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com"))
startActivity(intent)
외부 애플리케이션 실행
val context = LocalContext.current
Button(onClick = {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com"))
context.startActivity(intent)
}) {
Text("Open Google")
}
내부 컴포넌트 이동
Activity
와 Compose의 Composable 간 연결이 필요할 때 사용할 수 있습니다.특정 시스템 작업 요청
val context = LocalContext.current
Button(onClick = {
val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:123456789"))
context.startActivity(intent)
}) {
Text("Call")
}
데이터 공유
Intent
를 활용합니다.val context = LocalContext.current
Button(onClick = {
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "Hello from Compose!")
}
context.startActivity(Intent.createChooser(shareIntent, "Share via"))
}) {
Text("Share Text")
}
Compose의 내비게이션 시스템인 Jetpack Navigation Compose를 사용하는 경우, 화면 간의 이동은 NavController
를 통해 처리합니다. 이 경우 Intent
를 사용할 필요가 없습니다.
val navController = rememberNavController()
NavHost(navController, startDestination = "screen1") {
composable("screen1") { Screen1(navController) }
composable("screen2") { Screen2() }
}
@Composable
fun Screen1(navController: NavController) {
Button(onClick = { navController.navigate("screen2") }) {
Text("Go to Screen 2")
}
}