티스토리 뷰

Mobile/Android

[Android]AppWidgetProvider

out of coding 2015. 2. 26. 12:07

AppWidget을 만들어 볼까 합니다.

특별한 기능은 없는 클릭이벤트를 받게 되면 처리되는 부분만 만들겠습니다.


우선작성해야하는 부분들은 다음과 같습니다.


1. AppWidgetProvider Class를 상속받은 Provider Class


우선 안드로이드 제공하는 AppWidgetProvider를 상속받는 Class를 하나 만들어야 합니다.

이녀석은 BroadcastReceiver를 상속받도록 되어 있습니다.

구조상 이렇게 만든것 같습니다. RemoteView를 사용해야 하니까요.


이 AppWidgetProvider를 상속받은 Class는 메소드를 구현을 하여야 하는데요.

항상 그렇듯이 다 채워놓을 필요는 없고, 구상화하도록 메소드만 만들어줍니다.


public void onEnabled(Context context)

 : App Widget이 처음생성될 때 불립니다. 두번째 세번째도 아니고, 제일 처음 만들어질때 불려집니다.


public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)

 : Meta xml에 지정하여준 updatePeriodMillis값에 의해 주기적으로 호출되며, 처음 widget이 화면에 붙을때, init작업이 되도록 호출됩니다.

(Configuration activity를 따로 두었다면, 처음 붙을때는 호출되지 않습니다. activity가 호출됩니다.)


public void onDeleted(Context context, int[] appWidgetIds)

 : Widget이 삭제될때 호출됩니다.


public void onDisabled(Context context)

 : Widget의 마지막 녀석이 삭제될때 호출됩니다. 이 말이 무슨말이냐면, onEnabled와 마찬가지로 남아있는 녀석이 세개, 두개도 아닌 그 녀석이 마지막이어야 합니다.


public void onReceive(Context context, Intent intent)

 : BroadcastReceiver를 상속받아서 만들어져서, 이녀석을 구상화하여 주어야하는데, 내부적으로는 Callback method를 다 호출하여줍니다. 알아서...

그래서 특별한 경우가 아니라면, 작성할 이유는 없지만, Custom할 경우가 발생한다면 수정을 하여 주어야 합니다.


위젯이 update될 경우에 이쪽으로 Intent의 getAction값으로 AppWidgetManager.ACTION_APPWIDGET_UPDATE가 전달되며,

이 경우에 모든 위젯(보이도록 하여둔?)을 갱신하여 주어야 합니다.


제 소스에서는 updateUI에서 수정하게 되어 있습니다.


다음과 같은 소스상에서 구동이 되게 되겠네요.


String action = intent.getAction();


if(AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action) == true) {


} else if(AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) == true) {

AppWidgetManager manager = AppWidgetManager.getInstance(context);

updateUI(context, manager, manager.getAppWidgetIds(new ComponentName(context, getClass())));

} else if(AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action) == true) {


} else if(AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action) == true) {


} else if(ACTION_EVENT.equals(action) == true) {

Toast.makeText(context, "Get Event", Toast.LENGTH_SHORT).show();

}


2. 위젯에 보이는 View들의 컨트롤


저희가 만들려는 View는 우리의 앱보다는 다른쪽에 파견을 보낸 화면입니다.

그래서 직접적으로는 호출이 안되며, RemoteView라는 녀석을 사용하여야 합니다.

직접적이 아닌 간접적으로 너 이렇게 행동해. 클릭이 되면 어떤것들을 호출해 이런식이죠.

이렇게 개발한다 그래서 어렵게 되는건 아니고, 그냥 전달만 하여준다고 생각하시면 될것 같네요.


RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_custom);


Intent eventIntent = new Intent(ACTION_EVENT);

Intent activityIntent = new Intent(ACTION_CALL_MAIN_ACTIVITY);


PendingIntent pendingIntent_event = PendingIntent.getBroadcast(context, 0, eventIntent, PendingIntent.FLAG_UPDATE_CURRENT);

PendingIntent pendingIntent_activity = PendingIntent.getActivity(context, 0, activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);


views.setOnClickPendingIntent(R.id.button1, pendingIntent_activity);

views.setOnClickPendingIntent(R.id.button2, pendingIntent_event);


for(int appWidgetId : appWidgetIds) {

appWidgetManager.updateAppWidget(appWidgetId, views);

}


이러한 형식이 되겠죠.


3. Widget의 layout을 기술한 xml


우리는 화면을 만든 설계서를 안드로이드폰에게 전달을 하여야 합니다.

xml파일로 만들면 되고요. 중요한 부분은 몇가지 설정들이 있겠네요.


<?xml version="1.0" encoding="utf-8"?>

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"

android:initialLayout="@layout/widget_custom"

android:minHeight="250dp"

android:minWidth="250dp">

</appwidget-provider>


저는 4x4로 화면을 구성하려고 하여서 저런 수치를 넣게 되었습니다.

속성값들은 다음과 같습니다.


minWidth : 최소넓이

minHeight : 최소높이

updatePeriodMillis : onUpdate가 호출되는 주기

initalLayout : 레이아웃이 어떤것인지

configure : 설정화면 Activity


자 여기에서 cell의 사이즈를 어떻게 지정하면 되는것인지 궁금하실것입니다.

Developer site에서는 다음과 같이 작성하라고 되어 있고요.


1cell : 40dp

2cell : 110dp

3cell : 180dp

4cell : 250dp

ncell : 70 * n - 30 dp


이런형식으로 지정을 하여 주면 화면이 짜장하고 나옵니다.


Cells에 따른 크기 지정 및 Guide

http://developer.android.com/guide/practices/ui_guidelines/widget_design.html#design


4. manifest파일 속성지정


물론 minifest파일에 속성을 넣어주저야지만 외부에서 들어오는 값들과 설계도를 안드로이드에 넘겨주어야지 제대로 지정이 되겠죠.


예제는 다음과 같습니다.


<receiver android:name=".CustomWidget">

<meta-data

android:name="android.appwidget.provider"

android:resource="@xml/widget_custom_configuration"/>

<intent-filter>

<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>

<action android:name="com.example.appwidgettest.ACTION_EVENT"/>

</intent-filter>

</receiver>


위에 보면 android.appwidget.action.APPWIDGET_UPDATE는 앱의 위젯이 업데이트 되었다. 즉. 새로들어가거나, 다른것을 추가하였을 경우에

호출되도록 명시적으로 넣어주어야 합니다.


그 하단의 action은 custom하여 주는것이죠.


이후에 작업은 빌드를 하고 난후에, 런처에서 위젯을 넣어주면 되겠죠?

저는 구성하고 난 이후에 아래와 같이 나오게 되었습니다.




추가적인 부분은 소스를 전부넣는거 보다는 소스첨부를 확인하시는것이 더 편할것 같습니다.


첨부파일 : 구동되는 풀소스


AppWidgetTest.zip




'Mobile > Android' 카테고리의 다른 글

[Android]WebView를 JavaScript와 연동  (0) 2015.03.10
[Android]전화사용  (0) 2015.03.08
[Android]ListPopupWindow 예제  (0) 2015.02.25
[Android]Notification flag  (0) 2015.02.25
[Android]Sensor  (0) 2015.02.24
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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 29 30 31
글 보관함