앱 위젯 호스트는 구성 활동을 호출하며 구성 활동은 항상 결과를 반환해야 합니다. 결과에는 활동을 실행한 인텐트에 의해 전달된 앱 위젯 ID가 포함되어야 합니다(인텐트 추가 항목에 EXTRA_APPWIDGET_ID로 저장됨).
구성 활동이 실행될 때 시스템에서 ACTION_APPWIDGET_UPDATE 브로드캐스트를 보내지 않으므로 위젯이 생성될 때 onUpdate() 메서드를 호출하지 않습니다.
처음 위젯을 만들 때 AppWidgetManager에 업데이트를 요청하는 것은 구성 활동의 책임입니다. 하지만 이후 업데이트에서는 onUpdate()가 호출됩니다. 처음에만 건너뜁니다.
구성에서 결과를 반환하고 위젯을 업데이트하는 방법의 예는 다음 섹션의 코드 스니펫을 참고하세요.
구성 활동에서 위젯 업데이트
위젯이 구성 활동을 사용하는 경우 구성이 완료된 후 위젯을 업데이트하는 것은 활동의 책임입니다. AppWidgetManager에서 직접 업데이트를 요청하여 그렇게 할 수 있습니다.
사용자는 위젯을 길게 터치하고 그림 1에서 1로 표시된 재구성 버튼을 탭하여 위젯을 재구성할 수 있습니다.
그림 1. 위젯 재구성 버튼
위젯의 기본 구성 사용
사용자가 초기 구성 단계를 건너뛸 수 있도록 하면 더 원활한 위젯 환경을 제공할 수 있습니다. 이렇게 하려면 widgetFeatures 필드에 configuration_optional 및 reconfigurable 플래그를 모두 지정합니다. 이를 통해 사용자가 위젯을 추가한 후 구성 활동 실행을 우회할 수 있습니다. 앞서 언급했듯이 사용자는 나중에 위젯을 재구성할 수 있습니다. 예를 들어 시계 위젯은 초기 구성을 우회하고 기본적으로 기기 시간대를 표시할 수 있습니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2025-08-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-08-27(UTC)"],[],[],null,["App widgets can be configurable. For example, a clock widget can let users\nconfigure which time zone to display.\n\nIf you want to let users configure your widget's settings, create a widget\nconfiguration [`Activity`](/reference/android/app/Activity). This activity is\nautomatically launched by the app widget host either when the widget is created\nor later, depending on the [configuration options](#widget-config-options) you\nspecify.\n\nDeclare the configuration activity\n\nDeclare the configuration activity as a normal activity in the Android manifest\nfile. The app widget host launches it with the\n[`ACTION_APPWIDGET_CONFIGURE`](/reference/android/appwidget/AppWidgetManager#ACTION_APPWIDGET_CONFIGURE)\naction, so the activity needs to accept this intent. For example: \n\n \u003cactivity android:name=\".ExampleAppWidgetConfigurationActivity\"\u003e\n \u003cintent-filter\u003e\n \u003caction android:name=\"android.appwidget.action.APPWIDGET_CONFIGURE\"/\u003e\n \u003c/intent-filter\u003e\n \u003c/activity\u003e\n\nDeclare the activity in the `AppWidgetProviderInfo.xml` file with the\n`android:configure` attribute. See more information about\n[declaring this file](/guide/topics/appwidgets#AppWidgetProviderInfo). Here's an example of\nhow to declare the configuration activity: \n\n \u003cappwidget-provider xmlns:android=\"http://schemas.android.com/apk/res/android\"\n ...\n android:configure=\"com.example.android.ExampleAppWidgetConfigurationActivity\"\n ... \u003e\n \u003c/appwidget-provider\u003e\n\nThe activity is declared with a fully qualified namespace, because the launcher\nreferences it from outside your package scope.\n\nThat's all you need to start a configuration activity. Next, you need to\nimplement the actual activity.\n\nImplement the configuration activity\n\nThere are two important points to remember when you implement the activity:\n\n- The app widget host calls the configuration activity, and the configuration activity must always return a result. The result must include the App Widget ID passed by the intent that launched the activity---saved in the intent extras as [`EXTRA_APPWIDGET_ID`](/reference/android/appwidget/AppWidgetManager#EXTRA_APPWIDGET_ID).\n- The system doesn't send the [`ACTION_APPWIDGET_UPDATE`](/reference/android/appwidget/AppWidgetManager#ACTION_APPWIDGET_UPDATE) broadcast when a configuration activity is launched, which means it doesn't call the [`onUpdate()`](/reference/android/appwidget/AppWidgetProvider#onUpdate(android.content.Context,%20android.appwidget.AppWidgetManager,%20int[])) method when the widget is created. It's the responsibility of the configuration activity to request an update from the `AppWidgetManager` when creating the widget for the first time. However, `onUpdate()` is called for subsequent updates---it is only skipped the first time.\n\nSee the code snippets in the following section for an example of how to return a\nresult from the configuration and update the widget.\n\nUpdate the widget from the configuration activity\n\nWhen a widget uses a configuration activity, it's the responsibility of\nthe activity to update the widget when configuration is complete. You can do so\nby requesting an update directly from the\n[`AppWidgetManager`](/reference/android/appwidget/AppWidgetManager).\n\nHere's a summary of the procedure to properly update the widget and close the\nconfiguration activity:\n\n1. Get the App Widget ID from the intent that launched the activity:\n\n Kotlin \n\n ```kotlin\n val appWidgetId = intent?.extras?.getInt(\n AppWidgetManager.EXTRA_APPWIDGET_ID,\n AppWidgetManager.INVALID_APPWIDGET_ID\n ) ?: AppWidgetManager.INVALID_APPWIDGET_ID\n ```\n\n Java \n\n ```java\n Intent intent = getIntent();\n Bundle extras = intent.getExtras();\n int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;\n if (extras != null) {\n appWidgetId = extras.getInt(\n AppWidgetManager.EXTRA_APPWIDGET_ID,\n AppWidgetManager.INVALID_APPWIDGET_ID);\n }\n ```\n2. Set the activity result to `RESULT_CANCELED`.\n\n This way, if the user backs out of the activity before reaching the end, the\n system notifies the app widget host that the configuration is canceled and\n the host doesn't add the widget: \n\n Kotlin \n\n ```kotlin\n val resultValue = Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)\n setResult(Activity.RESULT_CANCELED, resultValue)\n ```\n\n Java \n\n ```java\n int resultValue = new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);\n setResult(Activity.RESULT_CANCELED, resultValue);\n ```\n3. Configure the widget according to the user's preferences.\n\n4. When the configuration is complete, get an instance of the\n `AppWidgetManager` by calling [`getInstance(Context)`](/reference/android/appwidget/AppWidgetManager#getInstance(android.content.Context)):\n\n Kotlin \n\n ```kotlin\n val appWidgetManager = AppWidgetManager.getInstance(context)\n ```\n\n Java \n\n ```java\n AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);\n ```\n5. Update the widget with a\n [`RemoteViews`](/reference/android/widget/RemoteViews) layout by calling\n [`updateAppWidget(int,RemoteViews)`](/reference/android/appwidget/AppWidgetManager#updateAppWidget(int,%20android.widget.RemoteViews)):\n\n Kotlin \n\n ```kotlin\n val views = RemoteViews(context.packageName, R.layout.example_appwidget)\n appWidgetManager.updateAppWidget(appWidgetId, views)\n ```\n\n Java \n\n ```java\n RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);\n appWidgetManager.updateAppWidget(appWidgetId, views);\n ```\n6. Create the return intent, set it with the activity result, and\n finish the activity:\n\n Kotlin \n\n ```kotlin\n val resultValue = Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)\n setResult(Activity.RESULT_OK, resultValue)\n finish()\n ```\n\n Java \n\n ```java\n Intent resultValue = new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);\n setResult(RESULT_OK, resultValue);\n finish();\n ```\n\nSee the\n[`ListWidgetConfigureActivity.kt`](https://github.com/android/user-interface-samples/blob/main/AppWidget/app/src/main/java/com/example/android/appwidget/rv/list/ListWidgetConfigureActivity.kt)\nsample class on GitHub for an example.\n\nWidget configuration options\n\nBy default, the app widget host only launches the configuration activity once,\nimmediately after the user adds the widget to their home screen. However, you\ncan specify options that let you enable users to reconfigure existing widgets or\nskip initial widget configuration by providing a default widget configuration.\n| **Note:** These options are only available starting in Android 12 (API level 31). You can specify them for previous versions of Android, but the system ignores them and follows the default behavior.\n\nEnable users to reconfigure placed widgets\n\nTo let users reconfigure existing widgets, specify the\n[`reconfigurable`](/reference/android/appwidget/AppWidgetProviderInfo#WIDGET_FEATURE_RECONFIGURABLE)\nflag in the\n[`widgetFeatures`](/reference/android/appwidget/AppWidgetProviderInfo#widgetFeatures)\nattribute of `appwidget-provider`. See the guide to [declaring the\n`AppWidgetProviderInfo.xml` file](/guide/topics/appwidgets#AppWidgetProviderInfo) for more\ninformation. For example: \n\n \u003cappwidget-provider\n android:configure=\"com.myapp.ExampleAppWidgetConfigurationActivity\"\n android:widgetFeatures=\"reconfigurable\"\u003e\n \u003c/appwidget-provider\u003e\n\nUsers can reconfigure their widget by touching \\& holding the widget and tapping\nthe **Reconfigure** button, which is labeled\n1 in figure 1.\n**Figure 1.** Widget **Reconfigure** button. **Note:** The `reconfigurable` flag was introduced in Android 9 (API level 28), but it was not widely supported until Android 12.\n\nUse the widget's default configuration\n\nYou can provide a more seamless widget experience by letting users skip the\ninitial configuration step. To do this, specify both the\n[`configuration_optional`](/reference/android/appwidget/AppWidgetProviderInfo#WIDGET_FEATURE_CONFIGURATION_OPTIONAL)\nand `reconfigurable` flags in the `widgetFeatures` field. This bypasses\nlaunching the configuration activity after a user adds the widget. As mentioned\npreviously, the user can still [reconfigure the widget](#reconfigure-widgets)\nafterward. For example, a clock widget can bypass the initial configuration and\nshow the device time zone by default.\n\nHere is an example of how to mark your configuration activity as both\nreconfigurable and optional: \n\n \u003cappwidget-provider\n android:configure=\"com.myapp.ExampleAppWidgetConfigurationActivity\"\n android:widgetFeatures=\"reconfigurable|configuration_optional\"\u003e\n \u003c/appwidget-provider\u003e"]]