대부분의 Android 지원 기기에서 사용할 수 있는 Android 홈 화면을 통해 사용자는 앱 위젯 (또는 위젯)을 삽입하고 콘텐츠에 빠르게 액세스할 수 있습니다. 홈 화면 대체 앱 또는 유사한 앱을 빌드하는 경우에는 AppWidgetHost를 구현하여 사용자가 위젯을 삽입하도록 허용할 수도 있습니다. 대부분의 앱에서는 이렇게 해야 할 필요가 없지만 자체 호스트를 만드는 경우 호스트가 암시적으로 동의하는 계약 의무사항을 이해해야 합니다.
이 페이지에서는 맞춤 AppWidgetHost의 구현과 관련된 책임을 중점적으로 설명합니다. AppWidgetHost를 구현하는 구체적인 예는 Android 홈 화면 LauncherAppWidgetHost의 소스 코드를 참고하세요.
다음은 맞춤 AppWidgetHost의 구현과 관련된 키 클래스와 개념의 개요입니다.
앱 위젯 호스트: AppWidgetHost는 UI에 위젯을 삽입하는 앱의 AppWidget 서비스와의 상호작용을 제공합니다. AppWidgetHost에는 호스트의 자체 패키지 내에서 고유한 ID가 있어야 합니다. 이 ID는 호스트에서 지속적으로 사용됩니다. ID는 일반적으로 앱에서 할당하는 하드 코딩 값입니다.
앱 위젯 ID: 각 위젯 인스턴스에는 바인딩 시 고유 ID가 할당됩니다. bindAppWidgetIdIfAllowed()을 참고하고 자세한 내용은 이어지는 위젯 바인딩 섹션을 참고하세요. 호스트는 allocateAppWidgetId()를 사용하여 고유 ID를 가져옵니다.
이 ID는 위젯이 호스트에서 삭제될 때까지 위젯의 전체 기간 동안 유지됩니다. 호스트별 상태(예: 위젯의 크기와 위치)는 호스팅 패키지에 의해 유지되고 앱 위젯 ID와 연결되어야 합니다.
앱 위젯 호스트 뷰: AppWidgetHostView는 위젯이 표시되어야 할 때마다 래핑되는 프레임이라고 생각할 수 있습니다. 위젯이 호스트에 의해 확장될 때마다 위젯이 AppWidgetHostView와 연결됩니다.
기본적으로 시스템은 AppWidgetHostView를 생성하지만 호스트는 이를 확장하여 자체 AppWidgetHostView 하위 클래스를 만들 수 있습니다.
하지만 이 단계는 첫 번째 단계일 뿐입니다. 런타임에 사용자는 호스트에 위젯을 추가할 수 있는 권한을 앱에 명시적으로 부여해야 합니다. 앱에 위젯을 추가할 수 있는 권한이 있는지 테스트하려면 bindAppWidgetIdIfAllowed() 메서드를 사용하세요. bindAppWidgetIdIfAllowed()에서 false를 반환하는 경우 앱에서 사용자에게 권한을 부여하도록 요청하는 대화상자를 표시해야 합니다. 현재 위젯 추가에 대해 '허용'하거나 향후 모든 위젯 추가에 대해 '항상 허용'합니다.
다음 스니펫은 대화상자를 표시하는 방법의 예를 보여줍니다.
Kotlin
valintent=Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply{putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId)putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,info.componentName)// This is the options bundle described in the preceding section.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS,options)}startActivityForResult(intent,REQUEST_BIND_APPWIDGET)
자바
Intentintent=newIntent(AppWidgetManager.ACTION_APPWIDGET_BIND);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,info.componentName);// This is the options bundle described in the preceding section.intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS,options);startActivityForResult(intent,REQUEST_BIND_APPWIDGET);
위젯을 추가할 때 앞에서 설명한 대로 위젯 ID를 할당합니다. 위젯이 호스트에서 삭제되면 deleteAppWidgetId()를 호출하여 위젯 ID를 할당 취소합니다.
위젯을 추가할 때 구성 활동을 실행해야 하는지 확인합니다. 일반적으로 호스트는 configuration_optional 및 reconfigurable 플래그를 모두 지정하여 위젯의 구성 활동이 있는 경우 이를 실행해야 하며 선택사항으로 표시되지 않습니다. 자세한 내용은 구성 활동에서 위젯 업데이트를 참고하세요. 대부분의 위젯은 이 단계를 완료해야 표시됩니다.
위젯은 AppWidgetProviderInfo 메타데이터에 기본 너비와 높이를 지정합니다. 이러한 값은 Android 12부터 targetCellWidth 및 targetCellHeight가 지정된 경우 셀에 정의되거나 minWidth 및 minHeight만 지정된 경우 dp에 정의됩니다. 위젯 크기 조정 속성을 참고하세요.
위젯이 이 dps 단위 이상으로 배치되었는지 확인하세요. 예를 들어 대부분의 호스트는 아이콘과 위젯을 그리드에 정렬합니다. 이 시나리오에서 호스트는 기본적으로 minWidth 및 minHeight 제약 조건을 만족하는 최소 개수의 셀을 사용하여 위젯을 추가합니다.
이전 섹션에 나열된 요구사항 외에 특정 플랫폼 버전에는 호스트에 새로운 책임을 부여하는 기능이 도입됩니다.
타겟팅된 Android 버전에 따라 접근 방식 결정
Android 12
Android 12 (API 수준 31)는 위젯 인스턴스가 옵션 번들에서 사용할 수 있는 가능한 크기 목록을 dp로 포함하는 추가 List<SizeF>를 번들로 제공합니다.
제공되는 크기 수는 호스트 구현에 따라 다릅니다. 일반적으로 호스트는 휴대전화의 경우 두 가지 크기(세로 모드, 가로 모드)를 제공하고 폴더블의 경우 네 가지 크기를 제공합니다.
AppWidgetProvider가 RemoteViews에 제공할 수 있는 서로 다른 RemoteViews의 수에는 MAX_INIT_VIEW_COUNT (16)의 제한이 있습니다.
AppWidgetProvider 객체는 RemoteViews 객체를 List<SizeF>의 각 크기에 매핑하므로 MAX_INIT_VIEW_COUNT 크기 이상을 제공하지 마세요.
Android 12에서는 dps에 maxResizeWidth 및 maxResizeHeight 속성도 도입합니다. 이러한 속성 중 하나 이상을 사용하는 위젯은 속성으로 지정된 크기를 초과하지 않는 것이 좋습니다.
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 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,["The Android home screen, available on most Android-powered devices, lets the\nuser embed [app widgets](/guide/topics/appwidgets/overview) (or *widgets* ) for\nquick access to content. If you're building a home screen replacement or a\nsimilar app, you can also let the user embed widgets by implementing\n[`AppWidgetHost`](/reference/android/appwidget/AppWidgetHost). This isn't\nsomething that most apps need to do, but if you are creating your own host, it's\nimportant to understand the contractual obligations a host implicitly agrees to. \n\nThis page focuses on the responsibilities involved in implementing a custom\n`AppWidgetHost`. For a specific example of how to implement an `AppWidgetHost`,\nlook at the source code for the Android home screen\n[`LauncherAppWidgetHost`](https://cs.android.com/android/platform/superproject/+/master:packages/apps/Launcher3/src/com/android/launcher3/widget/LauncherAppWidgetHost.java;l=57?q=LauncherAppWidgetHost).\n\nHere is an overview of key classes and concepts involved in implementing a\ncustom `AppWidgetHost`:\n\n- **App widget host** : the `AppWidgetHost` provides the interaction with the\n AppWidget service for apps that embed widgets in their UI. An `AppWidgetHost`\n must have an ID that is unique within the host's own package. This ID persists\n across all uses of the host. The ID is typically a hardcoded value that you\n assign in your app.\n\n- **App widget ID** : each widget instance is assigned a unique ID at the time\n of binding. See\n [`bindAppWidgetIdIfAllowed()`](/reference/android/appwidget/AppWidgetManager#bindAppWidgetIdIfAllowed(int,%20android.content.ComponentName))\n and, for more detail, the [Binding widgets](#bind) section that follows. The\n host obtains the unique ID using\n [`allocateAppWidgetId()`](/reference/android/appwidget/AppWidgetHost#allocateAppWidgetId()).\n This ID persists across the lifetime of the widget until it is deleted from the\n host. Any host-specific state---such as the size and location of the\n widget---must be persisted by the hosting package and associated with the\n app widget ID.\n\n- **App widget host view** : think of\n [`AppWidgetHostView`](/reference/android/appwidget/AppWidgetHostView) as a frame\n that the widget is wrapped in whenever it needs to be displayed. A widget is\n associated with an `AppWidgetHostView` every time the widget is inflated by the\n host.\n\n - By default, the system creates an `AppWidgetHostView`, but the host can create its own subclass of `AppWidgetHostView` by extending it.\n - Starting in Android 12 (API level 31), `AppWidgetHostView` introduces the the [`setColorResources()`](/reference/android/appwidget/AppWidgetHostView#setColorResources(android.util.SparseIntArray)) and [`resetColorResources()`](/reference/android/appwidget/AppWidgetHostView#resetColorResources()) methods for handling dynamically overloaded colors. The host is responsible for providing the colors to these methods.\n- **Options bundle** : the `AppWidgetHost` uses the options bundle to\n communicate information to the\n [`AppWidgetProvider`](/reference/android/appwidget/AppWidgetProvider)\n about how the widget is displayed---for example, the\n [list of size ranges](/guide/topics/appwidgets/layouts#provide-exact-layouts)---and whether the\n widget is on a lockscreen or the home screen. This information lets the\n `AppWidgetProvider` tailor the widget's contents and appearance based on how and\n where it is displayed. You can use\n [`updateAppWidgetOptions()`](/reference/android/appwidget/AppWidgetHostView#updateAppWidgetOptions(android.os.Bundle))\n and\n [`updateAppWidgetSize()`](/reference/android/appwidget/AppWidgetHostView#updateAppWidgetSize(android.os.Bundle,%20java.util.List%3Candroid.util.SizeF%3E))\n to modify a widget's bundle. Both of these methods trigger the\n [`onAppWidgetOptionsChanged()`](/reference/android/appwidget/AppWidgetProvider#onAppWidgetOptionsChanged(android.content.Context,%20android.appwidget.AppWidgetManager,%20int,%20android.os.Bundle))\n callback to the `AppWidgetProvider`.\n\nBinding widgets\n\nWhen a user adds a widget to a host, a process called *binding* occurs. Binding\nrefers to associating a particular app widget ID with a specific host and a\nspecific `AppWidgetProvider`.\n\nBinding APIs also make it possible for a host to provide a custom UI for\nbinding. To use this process, your app must declare the\n[`BIND_APPWIDGET`](/reference/android/Manifest.permission#BIND_APPWIDGET)\npermission in the host's manifest: \n\n \u003cuses-permission android:name=\"android.permission.BIND_APPWIDGET\" /\u003e\n\nBut this is just the first step. At runtime, the user must explicitly grant\npermission to your app to let it add a widget to the host. To test whether your\napp has permission to add the widget, use the\n[`bindAppWidgetIdIfAllowed()`](/reference/android/appwidget/AppWidgetManager#bindAppWidgetIdIfAllowed(int,%20android.content.ComponentName))\nmethod. If `bindAppWidgetIdIfAllowed()` returns `false`, your app must display a\ndialog prompting the user to grant permission: \"allow\" for the current widget\naddition, or \"always allow\" to cover all future widget additions.\n\nThis snippet gives an example of how to display the dialog: \n\nKotlin \n\n```kotlin\nval intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {\n putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)\n putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName)\n // This is the options bundle described in the preceding section.\n putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options)\n}\nstartActivityForResult(intent, REQUEST_BIND_APPWIDGET)\n```\n\nJava \n\n```java\nIntent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);\nintent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);\nintent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);\n// This is the options bundle described in the preceding section.\nintent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);\nstartActivityForResult(intent, REQUEST_BIND_APPWIDGET);\n```\n\nThe host must check whether the widget that a user adds needs configuration. For\nmore information, see [Enable users to configure app\nwidgets](/guide/topics/appwidgets/configuration).\n\nHost responsibilities\n\nYou can specify a number of configuration settings for widgets using the\n[`AppWidgetProviderInfo` metadata](/develop/ui/views/appwidgets#components).\nYou can retrieve these configuration options, covered in more detail in the\nfollowing sections, from the\n[`AppWidgetProviderInfo`](/reference/android/appwidget/AppWidgetProviderInfo)\nobject associated with a widget provider.\n\nRegardless of the version of Android you are targeting, all hosts have the\nfollowing responsibilities:\n\n- When adding a widget, allocate the widget ID as described earlier. When a\n widget is removed from the host, call\n [`deleteAppWidgetId()`](/reference/android/appwidget/AppWidgetHost#deleteAppWidgetId(int))\n to deallocate the widget ID.\n\n- When adding a widget, check whether the configuration activity needs to be\n launched. Typically, the host needs to launch the widget's configuration\n activity if it exists and isn't marked as optional by specifying both the\n `configuration_optional` and `reconfigurable` flags. See\n [Update the widget from the configuration activity](/guide/topics/appwidgets/configuration#update)\n for details. This is a necessary step for many widgets before they can display.\n\n | **Note:** Handle irregular cases where the configuration activity doesn't return or finishes with errors.\n- Widgets specify a default width and height in the `AppWidgetProviderInfo`\n metadata. These values are defined in cells---starting in\n Android 12, if `targetCellWidth` and `targetCellHeight` are\n specified---or dps if only `minWidth` and `minHeight` are specified. See\n [Widget sizing attributes](/guide/topics/appwidgets#widget-sizing-attributes).\n\n Make sure that the widget is laid out with at least this many dps. For\n example, many hosts align icons and widgets in a grid. In this scenario, by\n default the host adds the a widget using the minimum number of cells that\n satisfy the `minWidth` and `minHeight` constraints.\n\nIn addition to the requirements listed in the preceding section, specific\nplatform versions introduce features that place new responsibilities on the\nhost.\n\nDetermine your approach based on the targeted Android version\n\nAndroid 12\n\nAndroid 12 (API level 31) bundles an extra `List\u003cSizeF\u003e` that contains the list\nof possible sizes in dps that a widget instance can take in the options bundle.\nThe number of sizes provided depends on the host implementation. Hosts typically\nprovide two sizes for phones---portrait and landscape---and four sizes\nfor foldables.\n\nThere is a limit of `MAX_INIT_VIEW_COUNT` (16) on the number of different\n`RemoteViews` that an `AppWidgetProvider` can provide to\n[`RemoteViews`](/reference/android/widget/RemoteViews#RemoteViews(java.util.Map%3Candroid.util.SizeF,%20android.widget.RemoteViews%3E)).\nSince `AppWidgetProvider` objects map a `RemoteViews` object to each size in the\n`List\u003cSizeF\u003e`, don't provide more than `MAX_INIT_VIEW_COUNT` sizes.\n\nAndroid 12 also introduces the\n[`maxResizeWidth`](/reference/android/appwidget/AppWidgetProviderInfo#maxResizeWidth)\nand\n[`maxResizeHeight`](/reference/android/appwidget/AppWidgetProviderInfo#maxResizeHeight)\nattributes in dps. We recommend that a widget that uses at least one of these\nattributes doesn't exceed the size specified by the attributes.\n\nAdditional resources\n\n- See the [`Glance`](/jetpack/androidx/releases/glance) reference documentation."]]