转自: http://www.maxiaoguo.com/shipin/346.html
最近项目需要widget,最近做了一下,
要求如图
是一个widget
点击widget
要求 这个widget中的图标是实时更新的, 这个弹出框是一个activity 详情看上篇博客。
创建widget的过程
1、 先看AndroidManifest.xml
<!-- 桌面小控件 --> <service android:name=".service.WidghtService"/>
<receiver android:name=".widget.WidgetProvider"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> <span style="white-space:pre"> </span></intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widgetinfo" /> </receiver>
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="72dp" android:minHeight="72dp" android:updatePeriodMillis="0" android:initialLayout="@layout/widget_ico" > </appwidget-provider>
3、在配置文件中还提到一个WidgetProvider
package com.m4399.gamecenter.widget; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; import com.m4399.gamecenter.common.NativeGameDao; import com.m4399.gamecenter.service.WidghtService; public class WidgetProvider extends AppWidgetProvider { NativeGameDao dao; @Override public void onDeleted(Context context, int[] appWidgetIds) {//有部分被删除就会执行 // TODO Auto-generated method stub super.onDeleted(context, appWidgetIds); } @Override public void onEnabled(Context context) {//当第一次添加部件到卓面时会调用该 方法 // TODO Auto-generated method stub super.onEnabled(context); } @Override public void onDisabled(Context context) {//在最后一个同类型部件被删除的时候调用 context.stopService(new Intent(context, WidghtService.class)); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Intent intent = new Intent(context,WidghtService.class); intent.setAction(WidghtService.START_ACTION); intent.putExtra("update", true); context.startService(intent); } }
4、那我们需要新建一个service
package com.m4399.gamecenter.service; import java.io.InputStream; import java.util.Vector; import com.m4399.gamecenter.R; import com.m4399.gamecenter.common.NativeGameDao; import com.m4399.gamecenter.ui.ScDialogActivity; import com.m4399.gamecenter.util.AppUtils; import com.m4399.gamecenter.util.LogTag; import com.m4399.gamecenter.vo.GameInfo; import com.m4399.gamecenter.widget.WidgetProvider; import android.app.PendingIntent; import android.app.Service; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.IBinder; import android.widget.RemoteViews; public class WidghtService extends Service { public static String START_ACTION = "com.m4399.gamecenter.service.WidghtService"; private NativeGameDao dao; @Override public void onCreate() { super.onCreate(); } @Override public void onStart(Intent intent, int startId) { if(intent!=null){ Bundle data = intent.getExtras(); String action = intent.getAction(); if(data==null)return; boolean update = data.getBoolean("update");// 操作类型 if (START_ACTION.equals(action)) {// 注册流程 if(update){ RemoteViews mRemoteViews = buildUpdate(this); ComponentName thisWidget = new ComponentName(this, WidgetProvider.class); AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(thisWidget, mRemoteViews); } } } } @Override public void onDestroy() { super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return null; } private RemoteViews buildUpdate(final Context context) { final RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_ico); // rv.setImageViewBitmap(viewId, bitmap) Intent intent = new Intent(context, ScDialogActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); rv.setOnClickPendingIntent(R.id.widget_fl, PendingIntent.getActivity(context, 0,intent, 0)); Vector<GameInfo> s; if(dao==null){ dao = new NativeGameDao(context); } s = dao.getLastlyGame(); // Comparator comp=Collections.reverseOrder(); // Collections.sort(s, comp); Resources r = getResources(); InputStream is = r.openRawResource(R.drawable.transparent); BitmapDrawable bmpDraw = new BitmapDrawable(is); Bitmap bmp = bmpDraw.getBitmap(); for(int i=0;i<5;i++){ if(s!=null&&s.size()>i){ GameInfo gameInfo = s.get(i); //LogTag.showTAG_e("tag", gameInfo.name+"000"); if(gameInfo!=null){ Drawable drawableUnder = AppUtils.getIconFromPKname(context, gameInfo.packageName); if(drawableUnder!=null){ BitmapDrawable bitmapDrawableUnder = (BitmapDrawable)drawableUnder; Bitmap bitmapUnder = bitmapDrawableUnder.getBitmap().copy(Bitmap.Config.ARGB_8888, true); int size = s.size(); if(size==1){ rv.setImageViewBitmap(R.id.widget_ico_f, bitmapUnder); rv.setImageViewBitmap(R.id.widget_ico_s, bmp); rv.setImageViewBitmap(R.id.widget_ico_t, bmp); rv.setImageViewBitmap(R.id.widget_ico_fo, bmp); rv.setImageViewBitmap(R.id.widget_ico_fif, bmp); }else if(size==2){ switch (i) { case 0: rv.setImageViewBitmap(R.id.widget_ico_s, bitmapUnder); break; case 1: rv.setImageViewBitmap(R.id.widget_ico_f, bitmapUnder); break; } rv.setImageViewBitmap(R.id.widget_ico_t, bmp); rv.setImageViewBitmap(R.id.widget_ico_fo, bmp); rv.setImageViewBitmap(R.id.widget_ico_fif, bmp); }else if(size==3){ switch (i) { case 0: rv.setImageViewBitmap(R.id.widget_ico_t, bitmapUnder); break; case 1: rv.setImageViewBitmap(R.id.widget_ico_s, bitmapUnder); break; case 2: rv.setImageViewBitmap(R.id.widget_ico_f, bitmapUnder); break; } rv.setImageViewBitmap(R.id.widget_ico_fo, bmp); rv.setImageViewBitmap(R.id.widget_ico_fif, bmp); }else if(size==4){ switch (i) { case 0: rv.setImageViewBitmap(R.id.widget_ico_fo, bitmapUnder); break; case 1: rv.setImageViewBitmap(R.id.widget_ico_t, bitmapUnder); break; case 2: rv.setImageViewBitmap(R.id.widget_ico_s, bitmapUnder); break; case 3: rv.setImageViewBitmap(R.id.widget_ico_f, bitmapUnder); break; } rv.setImageViewBitmap(R.id.widget_ico_fif, bmp); } else if(size>4){ switch (i) { case 0: rv.setImageViewBitmap(R.id.widget_ico_fif, bitmapUnder); break; case 1: rv.setImageViewBitmap(R.id.widget_ico_fo, bitmapUnder); break; case 2: rv.setImageViewBitmap(R.id.widget_ico_t, bitmapUnder); break; case 3: rv.setImageViewBitmap(R.id.widget_ico_s, bitmapUnder); break; case 4: rv.setImageViewBitmap(R.id.widget_ico_f, bitmapUnder); break; default: break; } } } } } } if(s==null||s.size()==0){ rv.setImageViewBitmap(R.id.widget_ico_f, bmp); rv.setImageViewBitmap(R.id.widget_ico_s, bmp); rv.setImageViewBitmap(R.id.widget_ico_t, bmp); rv.setImageViewBitmap(R.id.widget_ico_fo, bmp); rv.setImageViewBitmap(R.id.widget_ico_fif, bmp); } return rv; } }
代码写的有点乱,逻辑走的不是很好。
5、service中提到一个R.layout.widget_ico 布局文件
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="72dp" android:layout_height="72dp" android:id="@+id/widget_fl" > <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:layout_gravity="bottom|left" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/game_frame_sc_back" android:layout_gravity="bottom|left" /> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:layout_gravity="bottom|left" > <ImageView android:layout_width="30dp" android:layout_height="30dp" android:id="@+id/widget_ico_f" android:layout_marginLeft="15dp" android:layout_marginBottom="15dp" /> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:layout_gravity="bottom|left" > <ImageView android:layout_width="30dp" android:layout_height="30dp" android:id="@+id/widget_ico_s" android:layout_marginLeft="12dp" android:layout_marginBottom="12dp" /> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:layout_gravity="bottom|left" > <ImageView android:layout_width="30dp" android:layout_height="30dp" android:id="@+id/widget_ico_t" android:layout_marginLeft="9dp" android:layout_marginBottom="9dp" /> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:layout_gravity="bottom|left" > <ImageView android:layout_width="30dp" android:layout_height="30dp" android:id="@+id/widget_ico_fo" android:layout_marginBottom="7dp" android:layout_marginLeft="7dp" /> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:layout_gravity="bottom|left" > <ImageView android:layout_width="30dp" android:layout_height="30dp" android:id="@+id/widget_ico_fif" android:layout_marginLeft="4dp" android:layout_marginBottom="5dp" android:layout_gravity="bottom|left" /> </LinearLayout> <LinearLayout android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="vertical" android:layout_gravity="bottom|left" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/game_frame_sc_front" android:layout_gravity="bottom|left" /> </LinearLayout> </FrameLayout>
更新widget的时候只要给service传个值就行了
Intent intent = new Intent(context,WidghtService.class); intent.setAction(WidghtService.START_ACTION); intent.putExtra("update", true); context.startService(intent);