[Android Studio] Widget 위젯 제작(해커톤 회고2)

2025. 2. 28. 23:49·개발일지

학습용 게임앱이다 보니 이미 짜여진 기능 외에 앱 안에 추가하는게 한계가 있었다.

우리말 퀴즈 쇼와 같이 제작한 앱은 초성퀴즈와 유의어퀴즈로 구성되어있고 사용자가 직접 문제를 구성하여 익히고 싶은 단어들을 등록할 수 있게 하였다. 영어단어들을 입력해놓고 틈날때마다 핸드폰 앱으로 보면서 외우는 것과 같은 느낌이다. 기능을 더 추가하고 싶어 고민하다가 이미 기획한 앱안에 새로운 기능을 덧붙이긴 앱의 정체성에서 조금멀어지는 느낌이 들었다. 그래서 간단한 위젯을 구현하기로 하였다.

앞서 위젯의 흐름을 말해보자면, 한국어기초사전 api 기반으로 매일 2번씩 예문을 제공하며 사용자에게 자연스럽게 노출하게 만드는 기능이다.

 

한국어기초사전

trans_lang string 0-11 선택 * 요청변수 ‘translated(다국어 번역 )’이 ‘y’일 경우 설정할 수 있다. - 번역 언어(기본값 0 - 전체 번역 언어) - 아래 값을 다중 선택할 수 있도록 콤마(,)로 구분하여 나열

krdict.korean.go.kr

 

한국어 기초사전 Open API 사용방법

먼저 한국어기초사전 api키를 발급받는다. 한국어기초사전 페이지에서는 검색 요청 변수와 검색 출력 결과 예시를 제공한다. 검색방식에 따라 아래와 같이 결과를 나올 수 있어, 쿼리시 출력결과를 보며, 원하는 값을 제공받아야 한다.

검색 요청 예시

먼저 구현한 결과를 보여주면, 알아야할 단어가 볼드체로 된 예문을 제공한다. 여기서 고려한 점은 사전에서 랜덤으로 단어를 가져오기에는 '나무', '자라'와 같은 난이도가 낮은 단어들이 대부분이였다. 따라서 웹상에서 무료로 돌아다니는 사설수능국어 단어모음집을 참고하여 234개의 단어를 json파일로 만들었다. 이 json파일에서 가시적, 거시적과 같이 활용하기 좋은 단어들로 구성되어 랜덤으로 한 단어를 뽑아온다.

사전 api로 예문을 한번 제공시 api를 두번 호출한다. 예를 들어, ‘비례’단어가 주단어라면 첫번째로는 비례 단어가 포함된 예문, 그리고 비례 단어의 뜻이다. 두번 호출하는 이유는 이 api는 예문과 단어뜻이 동시에 제공되지 않기에 각각 호출되는 xml구조를 보고 값을 가져왔다.

 

최초 예문 표시
클릭시 '단어: 단어설명' 제공


- 위젯

api가져오기

기초대사전 api를 가져오는 과정에서 api로 어떤 값을 가져올 수 있을지, 제공되는 형태를 보면서 값을 가져오는 것이 가장 중요하다.

 //1. 뜻 가져오기
    @GET("search")
    suspend fun getDefinition(
        @Query("key") apiKey: String,
        @Query("q") query: String
    ): WordResponse

    // 2. 예문 가져오기
    @GET("search")
    suspend fun getExample(
        @Query("key") apiKey: String,
        @Query("q") query: String,
        @Query("part") part: String = "exam"
    ): WordResponse

폰트 설정

위젯은 폰트변경을 지원하지 않았다. 조금 우회해야 하지만, 자체적으로 폰트 설정한 텍스트를 비트맵으로 그려서 출력해야 했다.

private fun createTextBitmap(text: String, highlightText: String, context: Context): Bitmap {
	         val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply {
                color = Color.DKGRAY // 기본 텍스트 색상
                textSize = 40f // 고정된 텍스트 크기
                typeface = Typeface.create(ResourcesCompat.getFont(context, R.font.chungjukimsaeng), Typeface.NORMAL)
            }

            // 이 부분에서 글자 수와 글자 크기를 기반으로 너비를 계산
            val charactersPerLine = 20 // 한 줄에 표시할 글자 수
            val layoutWidth = textPaint.measureText("가".repeat(charactersPerLine)).toInt()

            val spannable = SpannableString(text)
            val start = text.indexOf(highlightText)
            if (start != -1) {
                val end = start + highlightText.length
                spannable.setSpan(ForegroundColorSpan(Color.BLACK), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
                spannable.setSpan(StyleSpan(Typeface.BOLD), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            }

            val layout = StaticLayout.Builder.obtain(spannable, 0, spannable.length, textPaint, layoutWidth)
                .setAlignment(Layout.Alignment.ALIGN_CENTER)
                .setLineSpacing(1.0f, 1.0f)
                .setIncludePad(true)
                .build()

            val bitmap = Bitmap.createBitmap(layout.width, layout.height, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            layout.draw(canvas)

            return bitmap
        }

주기적인 업데이트

하루에 2번씩 자동으로 api를 호출하여, 새로운 예문, 단어, 해석을 보여준다. WorkManger을 사용하여, 앱을 실행시키지 않다도 자동으로 실행되도록 설정하였다.


해커톤끝나기 직전에, 정신없이 개발하였기에 어려움에 부딪혀 고민했던 부분들을 적어보았다.

'개발일지' 카테고리의 다른 글

|Android Studio|FrameLayout, constraintLayout(해커톤 회고1)  (0) 2025.02.24
'개발일지' 카테고리의 다른 글
  • |Android Studio|FrameLayout, constraintLayout(해커톤 회고1)
pooh2
pooh2
pooh2 님의 블로그 입니다.
  • pooh2
    푸
    pooh2
  • 전체
    오늘
    어제
    • 분류 전체보기 (9)
      • 개발일지 (6)
        • React (0)
        • ML (1)
        • TIL (2)
        • 트러블슈팅 (1)
      • others`>` (3)
        • 북 (2)
        • 자격증 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

    • 2025년 6월
    • 2025년 4월
  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
pooh2
[Android Studio] Widget 위젯 제작(해커톤 회고2)
상단으로

티스토리툴바