일단 위젯을 만들기 전에 필요한 파일들이 무엇인지 알아보겠습니다.
* UpdateService.java - 주기적인 실행을 위한 서비스 파일
* exratewidget_layout.xml - 위젯 레이아웃 파일
* exrate_widget.xml - 위젯 설정 파일
* 그럼 각각의 파일내부를 들쳐 보도록 하겠습니다. 간단하게 xml 파일부터 설명드립니다.
> AndroidManifest.xml
<service android:name=".UpdateService" android:label="UpdateService">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
< /service>
< !-- 리시버 등록 -->
<receiver android:name=".ExrateWidgetProvider" android:label="@string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/exrate_widget" />
< /receiver>
> exrate_widget.xml - 위젯 설정 파일
< appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/exratewidget_layout"
/>
> exratewidget_layout.xml - 위젯 레이아웃 파일
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" android:background="@drawable/w_back01"
android:padding="5px" android:gravity="center" android:id="@+id/ID_LAYOUT">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:id="@+id/ID_LAYOUT1">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:gravity="center"
android:layout_marginTop="5px" android:layout_marginLeft="0px">
<ImageView android:id="@+id/ID_IMG1" android:src="@drawable/n_kr"
android:adjustViewBounds="true" android:layout_width="16dip"
android:layout_height="10dip" android:visibility="visible"
android:gravity="center_vertical|center_horizontal"
android:layout_marginBottom="5px" android:layout_marginLeft="5px"
android:layout_marginTop="5px" />
<TextView android:id="@+id/ID_SIGN1" android:text="USD"
android:textSize="5pt" android:textStyle="bold"
android:layout_height="wrap_content" android:gravity="center_vertical|center_horizontal"
android:visibility="visible" android:layout_width="25dip" />
<TextView android:id="@+id/ID_BUY1" android:layout_width="47dip"
android:layout_height="wrap_content" android:visibility="visible"
android:text="0000.00" android:gravity="center_vertical|center_horizontal"
android:textSize="5pt" />
<TextView android:id="@+id/ID_SELL1" android:layout_width="47dip"
android:layout_height="wrap_content" android:visibility="visible"
android:text="0000.00" android:gravity="center_vertical|center_horizontal"
android:textSize="5pt" />
</LinearLayout>
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal" android:id="@+id/ID_LAYOUT2"
android:layout_marginTop="0px" android:layout_marginRight="10px">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:visibility="visible"
android:text="ANDROES" android:gravity="center_vertical"
android:layout_marginLeft="20px" android:textSize="5pt"
android:textStyle="bold" />
<TextView android:layout_width="fill_parent" android:text="00-00 00:00"
android:layout_height="wrap_content" android:textSize="5pt"
android:gravity="right" android:id="@+id/ID_DATE" android:textStyle="bold" />
</LinearLayout>
< /LinearLayout>
> UpdateService.java - 주기적인 실행을 위한 서비스 파일
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import android.app.AlarmManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
public class UpdateService extends Service {
private static int[] sAppWidgetIds;
private static final String TAG = "Androes UpdateService";
private DateFormat format = SimpleDateFormat.getTimeInstance(
SimpleDateFormat.MEDIUM, Locale.getDefault());
private static Context context;
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
SimpleDateFormat formatStr = new SimpleDateFormat("HHmm", Locale.KOREA);
Integer onlyHour = Integer.parseInt(formatStr.format(new Date()));
Logger.i(TAG, "Androes Onstart: " + onlyHour + " ... " + format.format(new Date()));
ExrateWidgetProvider.xmlViewParser(context);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
public static void regAppWidgetIds(Context _context, int[] widgetIds) {
context = _context;
sAppWidgetIds = widgetIds;
}
}
* ExrateWidgetProvider.java - 위젯 메인 파일
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import com.androes.exrate.Main.XmlData;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;
public class ExrateWidgetProvider extends AppWidgetProvider {
static final String TAG = "ANDROES";
private static AppWidgetManager appWidgetManager;
Intent intent;
PendingIntent pendingIntent;
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 (action.equals("CLICK_RELOAD")) {
Logger.d("Androes", "ACTION_CLICK_RELOAD");
Toast.makeText(context, "Data Collecting", Toast.LENGTH_SHORT).show();
xmlViewParser(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
Logger.d("Androes", "ACTION_APPWIDGET_UPDATE");
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)) {
Logger.d("Androes", "ACTION_APPWIDGET_DELETED");
final int appWidgetId = intent.getExtras().getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
this.onDeleted(context, new int[] { appWidgetId });
}
/*
* 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_ENABLED.equals(action)) {
Logger.d(TAG, "ACTION_APPWIDGET_ENABLED");
this.onEnabled(context);
} else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
Logger.d(TAG, "ACTION_APPWIDGET_DISABLED");
this.onDisabled(context);
} else {
super.onReceive(context, intent);
}
}
// @Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Logger.d(TAG, "onUpdate");
if (appWidgetIds == null) {
appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(
context, ExrateWidgetProvider.class));
}
if (appWidgetIds == null) {
Logger.d(TAG, "onUpdate appwidgetIds is null");
return;
}
this.appWidgetManager = appWidgetManager;
UpdateService.regAppWidgetIds(context, appWidgetIds);
// updatePeriodMillis 옵션 미사용시 아래 스크립트 이용
// updatePeriodMillis 옵션 사용시
xmlViewParser(context);
}
/*
* public static void buildUpdate(Context context, String time_str, int
* appWidgetId) { Logger.e(TAG,time_str); RemoteViews views= new
* RemoteViews(context.getPackageName(), R.layout.time_layout);
* views.setTextViewText(R.id.now_time, (CharSequence)time_str);
* appWidgetManager.updateAppWidget(appWidgetId, views); }
*/
public static void StartUpdate(Context context, int[] appWidgetsIds) {
Intent updateIntent = new Intent(context, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
updateIntent, 0);
if (pendingIntent == null)
Logger.e(TAG, "pendingIntent is null");
else
Logger.e(TAG, "pendingIntent is not null");
Calendar cal = Calendar.getInstance();
// Schedule alarm, and force the device awake for this update
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
int delay = 10000; // 10초: 10000 / 30분: 1800000
alarmManager.setRepeating(AlarmManager.RTC, cal.getTimeInMillis(), delay, pendingIntent);
}
public static void xmlViewParser(Context context) {
RemoteViews remoteViews;
ComponentName watchWidget;
// TODO Auto-generated method stub
remoteViews = new RemoteViews(context.getPackageName(),
R.layout.exratewidget_layout);
....
Intent intent = new Intent(context, ExrateWidgetProvider.class);
intent.setAction("CLICK_RELOAD");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,intent, 0);
remoteViews.setOnClickPendingIntent(R.id.ID_LAYOUT, pendingIntent);
watchWidget = new ComponentName(context, ExrateWidgetProvider.class);
appWidgetManager.updateAppWidget(watchWidget, remoteViews);
}
}
updatePeriodMillis 옵션 사용하지 않고 수동으로 업데이트를 이용하고자 할 경우에는
AndroidManifest.xml내 service 항목과 ExrateWidgetProvider.java내 StartUpdate(), UpdateService.java 는 필요없습니다.