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