07
09

https://github.com/kimmandoo/android-drill/tree/main/Widget

 

android-drill/Widget at main · kimmandoo/android-drill

๊ธฐ์ˆ  ์—ฐ์Šต์šฉ repo. Contribute to kimmandoo/android-drill development by creating an account on GitHub.

github.com

์œ„์ ฏ์„ ํ•œ ๋ฒˆ ์•Œ์•„๋ณด์ž, ์ด๋ฒˆ์— ํ•™์Šตํ•ด๋ณด๋ฉด์„œ ๊ธฐ๋กํ•œ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ผ์„œ ๊ณ„์† ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค.

https://developer.android.com/develop/ui/views/appwidgets?hl=ko

 

๊ฐ„๋‹จํ•œ ์œ„์ ฏ ๋งŒ๋“ค๊ธฐ  |  Views  |  Android Developers

์•ฑ ์œ„์ ฏ์€ ๋‹ค๋ฅธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ (์˜ˆ: ํ™ˆ ํ™”๋ฉด)์— ์‚ฝ์ž…๋˜์–ด ์ฃผ๊ธฐ์ ์ธ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์†Œํ˜• ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ทฐ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ทฐ๋ฅผ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์—์„œ๋Š” ์œ„์ ฏ์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์œ„์ ฏ ์ œ๊ณต์ž๋ฅผ

developer.android.com

์ผ๋‹จ ์ด๊ฑธ ํ† ๋Œ€๋กœ ์ž…๋ฌธํ•ด๋ดค๋‹ค. 

 

์œ„์ ฏ์€ ํ™ˆํ™”๋ฉด์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์•ฑ์˜ remote view๋ผ๊ณ  ์ƒ๊ฐํ•ด์•ผ๋œ๋‹ค. ์•ฑ๊ณผ๋Š” ๋‹ค๋ฅธ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง€๋ฉฐ ๋ฐ”๋กœ๊ฐ€๊ธฐ์˜ ํŠน์„ฑ์„ ๊ฐ€์ง๊ณผ ๋™์‹œ์— ์œ„์ ฏ๋งŒ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ–๊ณ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ฑ์— ์žˆ๋Š” ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ๋”ฐ๋กœ ์œ„์ ฏ์—์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํฌ๊ฒŒ 4๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

  • ์ •๋ณด
  • ์ปฌ๋ ‰์…˜
  • ๊ด€๋ฆฌ
  • ํ•˜์ด๋ธŒ๋ฆฌ๋“œ 

์ž์„ธํ•œ ์ •๋ณด๋Š” ๊ณต์‹๋ฌธ์„œ์— ๋“ค์–ด๊ฐ€๋ฉด ๋‚˜์˜จ๋‹ค. ํ˜„์žฌ ์œ„์น˜์—์„œ ์–ด๋–ค ๋ชฉ์ ์ง€๊นŒ์ง€์˜ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„๊ฐ™์€ ๊ฑธ ํ‘œ์‹œํ•˜๋ ค๋ฉด ์ •๋ณด์œ„์ ฏ์ด ์ ์ ˆํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ๋‚ ์”จ ์œ„์ ฏ์ด ์ •๋ณด ์œ„์ ฏ์— ํ•ด๋‹นํ•œ๋‹ค. ๊ทผ๋ฐ ๊ณต๋ถ€๋ฅผ ์ข€ ํ•ด๋ณด๋‹ˆ ์œ„์น˜๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์•„๋ž˜ ํŽ˜์ด์ง€๋ฅผ ์ข€ ๋” ์‚ดํŽด๋ด์•ผ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.

https://developer.android.com/about/versions/oreo/background-location-limits?hl=ko

 

๋ฐฑ๊ทธ๋ผ์šด๋“œ ์œ„์น˜ ์ œํ•œ  |  Android Developers

๋ฐฐํ„ฐ๋ฆฌ ์ ˆ์•ฝ์— ๋„์›€์ด ๋˜๋Š” ์œ„์น˜ ์•ก์„ธ์Šค ์ œํ•œ.

developer.android.com

# `AppWidgetProviderInfo`, `AppWidgetProvider`

์œ„์ ฏ์€ 2๊ฐ€์ง€ ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ `ํ•„์ˆ˜`๋‹ค. AppWidgetProviderInfo๋ž‘ AppWidgetProvider๋‹ค. xml๋กœ ์ •์˜๋œ Info์™€ ๋ธŒ๋กœ๋“œ์บ์Šค๋“œ ๋ฆฌ์‹œ๋ฒ„๋ฅผ ์ƒ์†๋ฐ›๋Š” Provider๋กœ ๋‚˜๋‰˜๊ณ , Info๋Š” Provider๋ฅผ ํฌํ•จํ•ด์„œ ์œ„์ ฏ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๊ฐ์ฒด๋‹ค. xml๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฐ์ฒด๋ผ์„œ ์ข€ ์–ด์ƒ‰ํ–ˆ๋‹ค.

`res/xml` ๋ฐ‘์— Info ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ค˜์•ผ๋œ๋‹ค.

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialKeyguardLayout="@layout/widget_layout"
    android:initialLayout="@layout/widget_layout"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:previewImage="@drawable/ic_launcher_foreground"
    android:resizeMode="horizontal|vertical"
    android:updatePeriodMillis="86400000"
    android:widgetCategory="home_screen">
</appwidget-provider>

๋ง๊ทธ๋Œ€๋กœ ์†์„ฑ์„ ๋‹ค ์ ์–ด๋‘” ๊ฒƒ์ธ๋ฐ, ํ™ˆํ™”๋ฉด์— ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ๋Š” ์œ„์ ฏ์ด๊ณ  ๊ฐฑ์‹  ์ฃผ๊ธฐ๋Š” 24์‹œ๊ฐ„์ด๋‹ค. (24*60*60*1000ms)

Android 12(21๋…„ 8์›”์— ์ •์‹ ์ถœ์‹œ ๋œ OS ๋ฒ„์ „์ด๋ผ ์ƒ๊ฐ๋ณด๋‹ค ์ตœ์‹ ์ด๋‹ค.)๋ถ€ํ„ฐ๋Š” Cell ๊ฐœ๋…์œผ๋กœ ์œ„์ ฏ์„ ๋ฐฐ์น˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `targetCellWidth`, `targetCellHeight`๋ฅผ ์กฐ์ ˆํ•ด์„œ ๋ช‡์นธ ์ฐจ์ง€ํ•˜๊ฒŒ ํ•  ๊ฑด์ง€ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ ์ด Cell ๊ธฐ์ค€์ด minWidth, Height ๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€๋ฐ ์•„์ง 12 ๋ฐ‘ ๋ฒ„์ „๋„ ์ƒ๋‹น์ˆ˜๋ผ ๊ผญ ๋‘˜๋‹ค ์„ ์–ธํ•ด์ค˜์•ผ๋œ๋‹ค.

 

๋‹คํฌ๋ชจ๋“œ๊ฐ™์€ ์‹œ์Šคํ…œ ์„ค์ •์„ ๋”ฐ๋ผ๊ฐ€๊ฒŒ ํ•˜๋Š” ์†์„ฑ๋„ ์žˆ๋‹ค.

android:widgetFeatures="widgetFeatures=reconfigurable|configuration_optional"

 

์œ„์—์„œ `AppWidgetProvider`๋Š” ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ๋ฆฌ์‹œ๋ฒ„๋ฅผ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋ผ๊ณ  ํ–ˆ๋‹ค. ๊ทธ ๋ง์€ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ์— ๋ฆฌ์‹œ๋ฒ„๋ฅผ ์„ ์–ธํ•ด์ค˜์•ผ๋œ๋‹ค๋Š” ๋ง๊ณผ ๋™์ผํ•˜๋‹ค.

<receiver android:name=".MyWidgetProvider" android:exported="false">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/widget_info" />
</receiver>

 ๋”ฐ๋กœ ๋งŒ๋“ค์–ด๋‘” Provider ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•ด์„œ receiver ์„ ์–ธ ํ•ด์ค€๋‹ค. ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์„ค์ •ํ•˜๋Š” info ๊ฐ์ฒด ์—ญ์‹œ๊ฐ™์ด ๋‹ฌ์•„์ค˜์•ผํ•œ๋‹ค.

 

์ด์ œ Provider ํด๋ž˜์Šค๋ฅผ ๋ณด์ž.

private const val TAG = "MyWidgetProvider"
class MyWidgetProvider : AppWidgetProvider() {
    override fun onReceive(context: Context?, intent: Intent?) {
        super.onReceive(context, intent)
    }

    override fun onUpdate(
        context: Context?,
        appWidgetManager: AppWidgetManager?,
        appWidgetIds: IntArray?
    ) {
        super.onUpdate(context, appWidgetManager, appWidgetIds)
        Log.d(TAG, "onUpdate: ")
    }

    override fun onAppWidgetOptionsChanged(
        context: Context?,
        appWidgetManager: AppWidgetManager?,
        appWidgetId: Int,
        newOptions: Bundle?
    ) {
        super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
        Log.d(TAG, "onAppWidgetOptionsChanged: ")
    }

    override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {
        super.onDeleted(context, appWidgetIds)
        Log.d(TAG, "onDeleted: ")
    }

    override fun onEnabled(context: Context?) {
        super.onEnabled(context)
        Log.d(TAG, "onEnabled: ")
    }

    override fun onDisabled(context: Context?) {
        super.onDisabled(context)
        Log.d(TAG, "onDisabled: ")
    }

    override fun onRestored(context: Context?, oldWidgetIds: IntArray?, newWidgetIds: IntArray?) {
        super.onRestored(context, oldWidgetIds, newWidgetIds)
        Log.d(TAG, "onRestored: ")
    }

    companion object {
        internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) {
            val views = RemoteViews(context.packageName, R.layout.widget_layout)
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

์ƒ๋ช…์ฃผ๊ธฐ์— ๋กœ๊ทธ๋ฅผ ์ฐ์–ด๋ณด๊ณ  ์ง์ ‘ ๊ฒฝํ—˜ํ•ด๋ณด๋‹ˆ ์•ฑ์˜ ์‹คํ–‰๊ณผ ๋…๋ฆฝ๋˜์–ด ์‹คํ–‰๋˜๋Š” ๊ฒŒ ์‹ ๊ธฐํ–ˆ๋‹ค. ์ผ๋‹จ ํ™ˆํ™”๋ฉด์— ์œ„์ ฏ์„ ์ƒ์„ฑํ•˜๊ณ  ๋‚˜๋ฉด `onUpdate`๊ฐ€ ์œ„์ ฏ ์‚ฌ์ด์ฆˆ ๋ณ€๊ฒฝ๊ฐ™์€ ์ƒํ™ฉ์—์„œ ํ˜ธ์ถœ๋œ๋‹ค. ์ •ํ™•ํžˆ๋Š” ์—…๋ฐ์ดํŠธ, ์‚ญ์ œ, ์„ค์ •, ์ค‘์ง€์™€ ๊ฐ™์€ ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•œ๋‹ค๊ณ  ๋ด์•ผ๋œ๋‹ค.

 

์ฒ˜์Œ ์ƒ์„ฑํ•  ๋•Œ๋Š” `onEnabled`๋กœ ์‹œ์ž‘ํ•ด์„œ -> `onUpdate` -> `onAppWidgetOptionsChanged` -> `onDeleted` -> `onDisabled` ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. `onReceive`๋Š” ๋ชจ๋“  ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ์™€ ์œ„ ์ฝœ๋ฐฑํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•˜๊ธฐ์ „์— ํ˜ธ์ถœ๋˜๋Š”๋ฐ ๋”ฐ๋กœ ๊ฑด๋“œ๋ฆด ํ•„์š”๋Š” ์—†์–ด๋ณด์ธ๋‹ค. ์ค‘์š”ํ•œ๊ฑด ์ด ์ฝœ๋ฐฑํ•จ์ˆ˜๋“ค์ด ๋ฉ”์ธ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ ๋‹ค๋Š” ์ ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋ฉ”์ธ์Šค๋ ˆ๋“œ์—์„œ ํ•˜๋ฉด ์•ˆ๋๋˜ ์ž‘์—…๋“ค์€ ์œ„์ ฏ์—์„œ๋„ ํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

 

Info ๊ฐ์ฒด์˜ updatePeriodMillis ์ฃผ๊ธฐ๋งˆ๋‹ค `onUpdate`๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค. ์ตœ์†Œ๊ฐ’์ด 30๋ถ„์œผ๋กœ ์ •ํ•ด์ ธ์žˆ๋Š” ๋“ฏ ํ•˜๊ณ , ์ด๊ฑฐ๋ณด๋‹ค ๋” ๋น ๋ฅธ ์ฃผ๊ธฐ๋ฅผ ์›ํ•˜๋ฉด WorkManager๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋  ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.

https://developer.android.com/develop/ui/views/appwidgets/advanced?hl=ko#periodic

 

๊ณ ๊ธ‰ ์œ„์ ฏ ๋งŒ๋“ค๊ธฐ  |  Views  |  Android Developers

์ด ํŽ˜์ด์ง€๋Š” Cloud Translation API๋ฅผ ํ†ตํ•ด ๋ฒˆ์—ญ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณ ๊ธ‰ ์œ„์ ฏ ๋งŒ๋“ค๊ธฐ ์ปฌ๋ ‰์…˜์„ ์‚ฌ์šฉํ•ด ์ •๋ฆฌํ•˜๊ธฐ ๋‚ด ํ™˜๊ฒฝ์„ค์ •์„ ๊ธฐ์ค€์œผ๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถ„๋ฅ˜ํ•˜์„ธ์š”. ์ด ํŽ˜์ด์ง€์—์„œ๋Š” ๋” ๋‚˜์€ ์‚ฌ์šฉ์ž ํ™˜

developer.android.com

 

onUpdate๊ฐ€ ์‚ฌ์‹ค ์œ„์ ฏ์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์ฝœ๋ฐฑํ•จ์ˆ˜๋‹ค. ๋ชจ๋“  ์ƒํ˜ธ์ž‘์šฉ์ด ์ด ์ฝœ๋ฐฑ์„ ํƒ€๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ, ๊ทธ๋ž˜์„œ DB์ž‘์—…๊ฐ™์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์ด ์•„๋‹Œ๊ฒฝ์šฐ์—๋Š” ์ด ์ฝœ๋ฐฑํ•จ์ˆ˜์—์„œ ๋‹ค ์ฒ˜๋ฆฌํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

 

์œ„์ ฏ์€ `RemoteView`์— ๊ธฐ๋ฐ˜ํ•˜๋Š”๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ๋ทฐ๋“ค์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์–ด(์ปค์Šคํ…€๋ทฐ๋Š” ์•ˆ๋œ๋‹ค.) ๋‚˜์ค‘์— ์ง์ ‘ ํ•˜๋‚˜์”ฉ ํ•ด๋ณด๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค. ๋‚˜๋Š” ์ผ๋‹จ FrameLayout์œผ๋กœ ์žก๊ณ  ํ…์ŠคํŠธ๋ทฐ๋งŒ ํ•˜๋‚˜ ๋„ฃ์–ด๋†”์„œ ์•„์ง RemoteView๋กœ ๋ญ˜ ํ•  ์ˆ˜ ์žˆ๋Š” ์ง€ ๊ฐ์ด ์•ˆ์˜จ๋‹ค. 

์ง€์›๋˜๋Š” ๋ ˆ์ด์•„์›ƒ, ๋ทฐ๋“ค์ด๋‹ค. 

# ์œ„์น˜์ •๋ณด๋ž‘ ์—ฎ์–ด๋ณด๋ ค๋ฉด?

์œ„์น˜๊ธฐ๋ฐ˜ ์„œ๋น„์Šค์˜ ์ผ๋ถ€๋ถ„์œผ๋กœ ์œ„์ ฏ์„ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ์ด๋ผ์„œ ์ด๊ฒŒ ์ œ์ผ ์ค‘์š”ํ•˜๋‹ค.

onUpdate์—์„œ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋œ๋‹ค๊ณ ๋Š” ํ•˜์ง€๋งŒ, ๋ธŒ๋กœ๋“œ์บ์ŠคํŠธ ๋ฆฌ์‹œ๋ฒ„๋ฅผ ์ƒ์†๋ฐ›์€ ํŠน์ง•์ด ๊ทธ๋Œ€๋กœ ์‚ด์•„์žˆ์–ด์„œ onUpdate๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๋‚˜์„œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‚ด์•„์žˆ๋‹ค๋Š” ๋ณด์žฅ์ด์—†๋‹ค. 

๋˜๊ธด ๋˜๋Š”๋ฐ ์ธํ„ฐ๋ฒŒ(์•ฝ 10๋ถ„)์ด ์ข€ ์‹ฌํ•˜๊ณ  ๊ธฐ์ค€์ด ๋ญ”์ง€๋ฅผ ๋ชจ๋ฅด๊ฒ ๋‹ค.

์ด ๋ถ€๋ถ„ ๋•Œ๋ฌธ์— ์š”์ฒญ์ด ์—„์ฒญ ๋Šฆ๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค... `FLP`๋กœ ์ „ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋˜ ์ฐพ์•„๋ด์•ผ๊ฒ ๋‹ค.

private const val TAG = "MyWidgetProvider"
class MyWidgetProvider : AppWidgetProvider() {

    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override fun onReceive(context: Context?, intent: Intent?) {
        super.onReceive(context, intent)
    }

    override fun onUpdate(
        context: Context?,
        appWidgetManager: AppWidgetManager?,
        appWidgetIds: IntArray?
    ) {
        super.onUpdate(context, appWidgetManager, appWidgetIds)
        Log.d(TAG, "onUpdate: ")
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)

        val locationRequest = LocationRequest.create().apply {
            interval = 1000
            fastestInterval = 500
            priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        }

        val locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                locationResult.lastLocation?.let { location ->
                    // ์œ„์น˜ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์œ„์ ฏ ์—…๋ฐ์ดํŠธ
                    Log.d(TAG, "onLocationResult: ${location}")
                }
            }
        }

        // ์œ„์น˜ ์—…๋ฐ์ดํŠธ ์š”์ฒญ
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
        }
    }

    override fun onAppWidgetOptionsChanged(
        context: Context?,
        appWidgetManager: AppWidgetManager?,
        appWidgetId: Int,
        newOptions: Bundle?
    ) {
        super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
        Log.d(TAG, "onAppWidgetOptionsChanged: ")
    }

    companion object {
        internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) {
            val views = RemoteViews(context.packageName, R.layout.widget_layout)
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

 

๋„์›€์ด ๋๋‹ค๋ฉด ๋Œ“๊ธ€์ด๋‚˜ ๊ณต๊ฐ ๋ฒ„ํŠผ ํ•œ ๋ฒˆ์”ฉ ๋ˆ„๋ฅด๊ณ  ๊ฐ€์ฃผ์„ธ์š”!

 

๋ฐ˜์‘ํ˜•
COMMENT