2020/03/09 - [Android/Widget] - 안드로이드 위젯 개발하기 (1)
2020/03/10 - [Android/Widget] - 안드로이드 위젯 개발하기 (2)
이전 글에서는 WidgetProvider 를 BroadcastReceiver 를 통해 구현한 것이었습니다.
class WidgetProvider : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
}
}
BroadcastReceiver 를 사용한 것은 Widget 을 개발하는데 있어 기본적인 동작을 확인하기 위함이었습니다.
개발자 문서에도 기술되어 있지만, WidgetProvider 는 BroadcastReceiver 보다는 AppWidgetProvider 로 구현하는 것이 좋습니다.
이유는 AppWidgetProvider 소스 코드에 다 나와있지만, 간단히 설명드리면,
위젯 설치 전후 받을 수 있는 모든 Intent Action 과 extra 에 대해 BroadcastReceiver 를 잘 풀어놓은 것이기 때문입니다.
이를 테면, ACTION_APPWIDGET_UPDATE action 은 onUpdate 함수에, ACTION_APPWIDGET_DELETED action 은 onDeleted 함수를 호출 하도록 되어 있습니다. 자세한 것은 AppWidgetProvder.java 소스 코드를 참조하세요.
class WidgetProvider : AppWidgetProvider() {
override fun onUpdate(context: Context?, manager: AppWidgetManager?, widgetIds: IntArray?) {
val remoteViews = RemoteViews(
"com.tistory.develop_branch.widget",
R.layout.widget_layout
)
widgetIds?.forEach {
manager?.updateAppWidget(it, remoteViews)
}
}
override fun onAppWidgetOptionsChanged(
context: Context?, appWidgetManager: AppWidgetManager?,
appWidgetId: Int, newOptions: Bundle?
) {
}
override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {}
override fun onEnabled(context: Context?) {}
override fun onDisabled(context: Context?) {}
override fun onRestored(
context: Context?,
oldWidgetIds: IntArray?,
newWidgetIds: IntArray?
) {
}
}
여기서 잠시 맨 처음 글에서 언급하였던 <receiver> 태그에 대해서 다시 이야기해 보죠.
<receiver android:name=".WidgetProvider" >
<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>
AndroidManifest.xml 파일에 기술해 놓았던 <intent-filter> 는 "android.appwidget.action.APPWIDGET_UPDATE" action 뿐이었습니다.
하지만, 알고보면 AppWidgetProvider 는 APPWIDGET_UPDATE 뿐만아니라, APPWIDGET_DELETED, APPWIDGET_ENABLED, APPWIDGET_DISABLED, APPWIDGET_OPTION_CHANGED, APPWIDGET_RESTORED action 도 받아서 처리하고 있습니다.
이는 시스템에서 두 가지 값 APPWIDGET_UPDATE action intent filter 와 "android.appwidget.provider" meta-data 를 가지고 있는 경우에 대해서 명시적인 Intent 를 보내주고 있다는 의미입니다.
다시 말하면, APPWIDGET_DELETED 를 intent-filter 로 추가하지 않아도, 해당 이벤트를 수신할 수 있고, 설령 추가하지 않는다하더라도 항상 이벤트를 수신하는데는 문제가 없다는 얘기입니다.
덧붙임 1.
AndroidManifest.xml 파일에서 android:exported=false 를 추가해놓을 경우, Intent 를 받지 못한다는 경우가 종종 있는 것 같습니다.
물론, 저는 겪어 보지 않았습니다만, 스택오버플로우에서 종종 볼 수 있는 질문입니다.
'Android Widget' 카테고리의 다른 글
안드로이드 위젯 개발하기 (4) (0) | 2020.07.27 |
---|---|
안드로이드 위젯 개발하기 (2) (0) | 2020.03.10 |
안드로이드 위젯 개발하기 (1) (0) | 2020.03.09 |