일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- notification
- CoordinatorLayout
- ViewModel
- kotlin
- View
- LiveData
- CollapsingToolbarLayout
- 알림
- room
- Android
- BOJ
- 알고리즘
- AppBarLayout
- sqlite
- lifecycle
- HTTP
- Behavior
- 안드로이드
- onLayout
- Coroutine
- Navigation
- onMeasure
- recyclerview
- hilt
- 백준
- Algorithm
- 코틀린
- DataBinding
- activity
- CustomView
- Today
- Total
개발일지
Android Widget - 위젯 이벤트 본문
AppWidgetProvider
안드로이드에서 Widget에 관련된 생성, 삭제, 수정 등 이벤트를 제공하며 BroadcastReceiver를 통해 이벤트를 수신할 수 있습니다. 안드로이드에서 이러한 이벤트를 쉽게 처리하기 위해 AppWidgetProvider를 제공합니다.
실제로 내부 코드를 보면 BroadcastReceiver를 상속받고 onReceive에서 Action으로 분기하여 onEnabled, onDeleted등 함수를 호출합니다. 즉 개발자는 AppWidgetProvider를 상속받고 해당 함수를 오버로딩하면 됩니다.
public class AppWidgetProvider extends BroadcastReceiver {
public AppWidgetProvider() {
}
public void onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
} else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
this.onDeleted(context, new int[] { appWidgetId });
}
} else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
&& extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
appWidgetId, widgetExtras);
}
} else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
this.onDisabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (oldIds != null && oldIds.length > 0) {
this.onRestored(context, oldIds, newIds);
this.onUpdate(context, AppWidgetManager.getInstance(context), newIds);
}
}
}
}
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
}
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, Bundle newOptions) {
}
public void onDeleted(Context context, int[] appWidgetIds) {
}
public void onEnabled(Context context) {
}
public void onDisabled(Context context) {
}
public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
}
}
onUpdate
updatePeriodMillis
에 맞춰서 호출됩니다. 최소 주기를 30분으로 설정할 수 있으며 그 이하로 설정한 경우 무시되어 30분마다 onUpdate를 호출합니다.(자주 업데이트가 필요한 경우 AlarmManager를 사용하면 됩니다.) 또한 위젯이 처음 생성될 때 호출되기 때문에 개발자는 onUpdate에 RemoteViews를 업데이트하는 로직을 작성하면 됩니다.
인스턴스별로 updatePeriodMillis를 따르는 것이 아닌. 모든 인스턴스가 같이 updatePeriodMillis에 맞춰 업데이트 됩니다. 예를 들어 2시간 간격으로 업데이트 되는 위젯인 경우 첫번째 위젯이 생성된 후 1시간 후에 두번째 위젯이 생성된 경우, 두번째 위젯은 1시간 후에 onUpdate를 호출합니다.
ACTION_APPWIDGET_UPDATE의 Action을 받을 때 호출되며, Widget아이디는 EXTRA_APPWIDGET_IDS를 통해 IntArray형식으로 제공됩니다.
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
}
onAppWidgetOptionsChanged
위젯이 처음 생겨서 위치할 때와, 위젯의 크기가 변경될 때 호출됩니다. 주로 크기가 변경되어 위젯의 내용이 수정될 때 사용합니다. 아래와 같은 Key로 제공받는 Bundle로 부터 dp값을 얻을 수 있습니다.
- AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH
- AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT
- AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH
- AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT
- AppWidgetManager.OPTION_APPWIDGET_SIZE
ACTION_APPWIDGET_OPTIONS_CHANGED의 Action을 받을 때 호출되며 EXTRA_APPWIDGET_ID를 통해 Int형식으로 Widget아이디를 제공받고, EXTRA_APPWIDGET_OPTIONS를 통해 Bundle을 제공받습니다.
} else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
&& extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS);
this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
appWidgetId, widgetExtras);
}
}
onDeleted
위젯이 삭제될 때마다 호출됩니다. 제공받는 widgetId로 작업을 처리할 수 있습니다.
ACTION_APPWIDGET_DELETE의 Action으로 호출되며 EXTRA_APPWIDGET_ID를 통해 Int형으로 widgetId를 제공받지만 IntArray를 만들어서 함수를 호출합니다.
} else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
Bundle extras = intent.getExtras();
if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
this.onDeleted(context, new int[] { appWidgetId });
}
}
onEnabled, onDisabled
위젯이 활성화/비활성화될 때마다 호출됩니다. 위젯의 인스턴스가 처음으로 생길 때 활성화되고, 모든 인스턴스가 사라질 때 비활성화 됩니다.
ACTION_APPWIDGET_ENABLED, ACTION_APPWIDGET_DISABLED를 통해 실행됩니다.
} else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
this.onEnabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
this.onDisabled(context);
}
Git (예제 코드)
https://github.com/KangTaeJong98/TaeTae98/tree/main/Android/Widget
GitHub - KangTaeJong98/TaeTae98: Study Repository
Study Repository. Contribute to KangTaeJong98/TaeTae98 development by creating an account on GitHub.
github.com
'Android (안드로이드) > Widget' 카테고리의 다른 글
Android in A..Z - Widget (생성) (0) | 2021.12.01 |
---|