번역자가 번역을 테스트할 앱이 필요하다. 번역만 하고 테스트를 못하면, 새 버전이 업데이트될 때 확인해야 하는데 이건 너무 못난이 같다.
일단은 아파치 POI 라이브러리를 이용했다. 스크린샷 터치에서 xlsx 파일을 읽어들여 메모리에 스트링을 로드해서 Restring에 초기화했다. POI 예제는 https://howtodoinjava.com/apache-commons/readingwriting-excel-files-in-java-poi-tutorial/ 참고바란다.
안드로이드에서 편하게 사용하기위해서 wrapping 라이브러리를 이용한다. 릴리스모드에서 프로가드를 이용하므로 proguard 모듈도 추가했다.
build.gradle 파일
implementation "com.github.SUPERCILEX.poi-android:poi:3.17"
implementation "com.github.SUPERCILEX.poi-android:proguard:3.17"
release모드에서 프로가드로 인해서 제대로 동작하지 않아서 프로가드 rule을 추가했다.
build.gradle 파일
buildTypes {
release {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-poi.pro'
signingConfig signingConfigs.release
}
}
proguard-poi.pro 파일
-keeppackagenames org.apache.poi.ss.formula.function
-keep class org.apache.poi.** {*;}
-keep class org.apache.xmlbeans.** {*;}
-keep class org.openxmlformats.** {*;}
-keep class org.openxmlformats.schemas.** {*;}
-keep class org.w3c.** {*;}
-keep class org.dom4j.** {*;}
-keep class org.etsi.** {*;}
-keep class com.fasterxml.** {*;}
-keep class schemasMicrosoftComVml.** {*;}
-keep class schemasMicrosoftComOfficeExcel.** {*;}
-keep class schemasMicrosoftComOfficeOffice.** {*;}
-keep class com.microsoft.schemas.** {*;}
-keep class com.graphbuilder.** {*;}
-dontwarn org.etsi.**
-dontnote com.microsoft.schemas.**
-dontnote com.graphbuilder.**
-dontwarn org.openxmlformats.**
-dontwarn org.w3c.**
-dontwarn org.dom4j.**
-dontwarn schemasMicrosoftComVml.**
-dontwarn schemasMicrosoftComOfficeExcel.**
-dontwarn schemasMicrosoftComOfficeOffice.**
-dontwarn schemasMicrosoftComOfficeWord.**
Download폴더에 xlsx파일을 내려받고 테스트 코드를 작성했다. 테스트를 위한 것이라 치환등은 하지 않았다.
RstringHelper.kt 파일
package com.mdiwebma.screenshot
import android.content.Context
import android.os.Environment
import android.util.Log
import android.widget.Toast
import com.ice.restring.Restring
import com.ice.restring.RestringConfig
import com.mdiwebma.base.flavor.RestringHelperBase
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.File
import java.io.FileInputStream
import java.util.*
class RestringHelper : RestringHelperBase {
companion object {
const val XLSX_FILENAME = "Screenshot_touch_translation.xlsx"
}
override fun init(context: Context) {
Restring.init(context,
RestringConfig.Builder()
.persist(false)
//.stringsLoader(MyStringsLoader())
.build()
)
Restring.setStrings(Locale.getDefault().language, loadStrings(context))
}
override fun wrapContext(context: Context): Context {
return Restring.wrapContext(context)
}
private fun loadStrings(context: Context): HashMap<String, String> {
val stringsMap = HashMap<String, String>()
try {
// Creating Input Stream
val path = Environment.getExternalStorageDirectory().absolutePath + "/Download/$XLSX_FILENAME"
val file = File(path)
val myInput = FileInputStream(file)
val workbook = XSSFWorkbook(myInput)
var rowindex = 8
var columnindex = 5 //ko
val sheet = workbook.getSheetAt(0)
val rows = sheet.getPhysicalNumberOfRows()
while (rowindex < rows) {
val row = sheet.getRow(rowindex) ?: break
//val cells = row.getPhysicalNumberOfCells()
val stringId = row.getCell(0)?.stringCellValue
if (stringId == "[app]") {
rowindex++
continue
}
if (stringId == "--end--") {
break
}
val stringText = row.getCell(columnindex)?.stringCellValue
if (stringId != null && stringText != null) {
Log.v("__T", "$stringId = $stringText")
stringsMap[stringId] = stringText
}
rowindex++
}
} catch (ex: Exception) {
Log.e("__T", "error", ex)
Toast.makeText(context, ex.message, Toast.LENGTH_LONG).show()
}
return stringsMap
}
}
구현 동작을 테스트해보니 클래스를 못 찾는 문제가 있어서 구글링으로 해결책을 찾았다.
MyApplication.java 파일
System.setProperty("org.apache.poi.javax.xml.stream.XMLInputFactory", "com.fasterxml.aalto.stax.InputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLOutputFactory", "com.fasterxml.aalto.stax.OutputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLEventFactory", "com.fasterxml.aalto.stax.EventFactoryImpl");
최종 릴리스 apk가 3메가 정도 늘어났다. POI 라이브러를 이용해서 구현하기는 했지만 이 방식보다는 google 스프레드시트 파일을 json파일로 내려받아서 처리하는 것으로 최종 버전이다. json으로 내려받는 것은 공식적으로 노출되지 않는 것 같았지만 구글링해보니 내부적으로 사용하는 api가 있었다. json으로 내려받지 못 한다면 POI를 이용한 방식이 여전히 필요하다.