WearOS 용 Compose에서 Watch 단독사용을 가정한 설명입니다. 단순 언어 변경은 휴대폰과 페어링 돼있으면 6번은 할 필요 없이 안드로이드 디벨로퍼 사이트 단계를 따라 하시면 됩니다.
회사 프로젝트 중 워치에서 단독으로 다국어 지원할 경우가 생겨 구현해 봤습니다. 일반적인 워치앱은 휴대폰과 언어 설정이 동기화되어 코드로 강제전환 시킬 필요가 없지만 워치 단독 사용을 가정한 앱이라 넣었습니다.
과정
- string.xml 정의 <- 이거 진짜! 다국어 지원하실 거면 미리미리 해 놓는 게 좋아요
- string edior로 번역 추가
- xml/locals_config.xml 정의
- Build.gradle 설정
- Manifest 서비스 추가 (Android12 및 이전 버전을 지원하는 앱 일경우 필요한 단계입니다)
- 인앱 언어선택 구현
string.xml 정의
하드코딩 된 문자열 들 중 UI에 사용되는 부분만 string.xml 에 정의해 줍니다.
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Column {
Text(text = "제우스")
Text(text = "오너")
Text(text = "페이커")
Text(text = "구마유시")
Text(text = "케리아")
Text(text = "톰 대행")
}
}
위 코드에서 문자열 부분을 string.xml 에 정의합니다.
<resources>
<string name="zeus">제우스</string>
<string name="oner">오너</string>
<string name="faker">대상혁</string>
<string name="guma">구마유시</string>
<string name="keria">케리아</string>
<string name="tom">톰 대행</string>
</resources>
이제 컴포저블로 돌아가서 하드코딩 대신 리소스테서 받도록 수정해 줍니다.
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Column {
Text(text = stringResource(id = R.string.zeus))
Text(text = stringResource(id = R.string.oner))
Text(text = stringResource(id = R.string.faker))
Text(text = stringResource(id = R.string.guma))
Text(text = stringResource(id = R.string.keria))
Text(text = stringResource(id = R.string.tom))
}
}
editor로 번역
string.xml에서 open editor를 눌러 string editory로 이동해 줍니다
지구본을 눌러 지원할 언어를 선택해 줍니다
이제 잘 번역해 줍니다. 동일하게 한국어도 작성해 줍니다
(디폴트 언어설정으로 돌아가는 방법을 몰라 한국어를 추가했습니다)
locales_config.xml 정의
res/xml 디렉터리에서 locales_config.xml을 생성 후 지원할 언어를 정의해 줍니다.
(xml 디렉터리가 없다면 직접 만들어주시면 됩니다)
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="ko"/>
<locale android:name="en"/>
</locale-config>
모든 언어코드는 아래 디벨로퍼 사이트를 참고하시면 됩니다.
build.gradle 설정
android {
compileSdk 34
defaultConfig {
...
resourceConfigurations+=["en", "ko"]
}
gradle에서 지원되는 언어를 resourceConfigurations 속성을 사용하여 지정해 줍니다
resourceConfigurations 속성이 있으면 빌드 시스템은 지정된 언어의 APK에만 언어 리소스를 포함하므로 앱에서 지원하지 않는 언어를 지원할 수 있는 다른 라이브러리의 번역된 문자열이 포함되지 않습니다. 자세한 내용은 앱에서 지원하는 언어 지정을 참고하세요.
Manifest 수정(Android 12 이하)
<application
...
android:localeConfig="@xml/locales_config"
android:theme="@android:style/Theme.DeviceDefault">
<!--다국어지원 서비스-->
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
...
</application>
만약 Android12 및 이전 버전을 지원하는 앱이라면 AppLocalesMetadataHolderService로 AndroidX에 언어 저장소를 처리하도록 지시합니다.
인앱 언어선택 구현
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
val localeManager = LocalContext.current.getSystemService(LocaleManager::class.java)
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text = stringResource(id = R.string.zeus))
Text(text = stringResource(id = R.string.oner))
Text(text = stringResource(id = R.string.faker))
Text(text = stringResource(id = R.string.guma))
Text(text = stringResource(id = R.string.keria))
Text(text = stringResource(id = R.string.tom))
Button(onClick = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
localeManager.applicationLocales = LocaleList.forLanguageTags("ko")
} else{
LocaleListCompat.forLanguageTags("ko")
}
}) {
Text(text = "한국어")
}
Button(onClick = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
localeManager.applicationLocales = LocaleList.forLanguageTags("en")
} else{
LocaleListCompat.forLanguageTags("ko")
}
}) {
Text(text = "English")
}
}
}
컴포즈 + wear OS + 단독사용이라는 조건을 가정해서 만든 샘플이지만 앱 자체에서 언어를 변경해야 하는 컴포즈 앱 일 경우 유용하게 사용하실 수 있습니다.
참고
'안드로이드 > 응용' 카테고리의 다른 글
FusedLocationService로 위치 조회 (0) | 2023.09.25 |
---|---|
SingleTon Holder로 편하게 SingleTon 쓰기 (0) | 2023.09.22 |
ApplicationContext 일반 클래스에서 쓰기 (0) | 2023.09.22 |