1.绘制图标
这里以动态修改桌面时钟的图标为例:
根据时间的不同,来旋转指针的方向,从而模拟出动态的时钟效果:
com.android.launcher3.Utilities
static Bitmap createClockIconBitmap(Context context){
Resources resources = context.getResources();
Drawable icon_drawable = resources.getDrawable(R.drawable.clock_bg);
Bitmap mBgBitmap = createIconBitmap(icon_drawable,context);
Bitmap mHourBitmap = BitmapFactory.decodeResource(
context.getResources(), R.drawable.clock_h);
Bitmap mMinutesBitmap = BitmapFactory.decodeResource(
context.getResources(), R.drawable.clock_m);
Time mCalendar = new Time();//获取当前时间
mCalendar.setToNow();
int hour = mCalendar.hour;
int minute = mCalendar.minute;
int second = mCalendar.second;
float mMinutes = minute + second / 60.0f;
float mHour = hour + mMinutes / 60.0f;
synchronized (sCanvas) {
final Canvas canvas = sCanvas;
canvas.setBitmap(mBgBitmap);
Paint mPaint = new Paint();
int x = mBgBitmap.getWidth() / 2;
int y = mBgBitmap.getHeight() / 2;
//sCanvas.drawBitmap(mBgBitmap, x - mBgBitmap.getWidth() / 2, y - mBgBitmap.getHeight() / 2, mPaint);
sCanvas.save();
sCanvas.rotate(mHour / 12.0f * 360.0f, x, y);
sCanvas.drawBitmap(mHourBitmap, x - mHourBitmap.getWidth() / 2, y - mHourBitmap.getHeight() / 2, mPaint);
sCanvas.restore();
sCanvas.save();
sCanvas.rotate((mMinutes / 60.0f * 360.0f - 180.0f), x, y);
sCanvas.drawBitmap(mMinutesBitmap, x - mMinutesBitmap.getWidth() / 2, y - mMinutesBitmap.getHeight() / 2, mPaint);
sCanvas.restore();
canvas.setBitmap(null);
}
return mBgBitmap;
}
2.监听时间更新
com.android.launcher3.LauncherAppState的作用是完成项目的一些初始化工作,以前在Application里面做的事情都放在了这里,所以可以在这里面注册广播,来监听时间的更新
filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_DATE_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(Intent.ACTION_TIME_TICK);
sContext.registerReceiver(mModel, filter);
3.接收时间更新事件
com.android.launcher3.LauncherModel extends BroadcastReceiver用于接收我们之前注册的广播
else if(Intent.ACTION_DATE_CHANGED.equals(action) ||
Intent.ACTION_TIME_CHANGED.equals(action) ||
Intent.ACTION_TIMEZONE_CHANGED.equals(action)||
Intent.ACTION_TIME_TICK.equals(action)){
final String packageNameClock ="com.android.deskclock";
onPackageChanged(packageNameClock,UserHandleCompat.myUserHandle());//通知更新图标
}
@Override
public void onPackageChanged(String packageName, UserHandleCompat user) {
int op = PackageUpdatedTask.OP_UPDATE;
enqueuePackageUpdated(new PackageUpdatedTask(op, new String[] { packageName },
user));
}
void enqueuePackageUpdated(PackageUpdatedTask task) {
sWorker.post(task);//handler.post(runnable)
}
4.更新图标
com.android.launcher3.BubbleTextView是一个自定义的TextView,用来显示桌面的应用图标,所以在这里可以根据包名来拦截应用图标,并修改成我们想要的图标
public void applyFromApplicationInfo(AppInfo info) {
if(info instanceof AppInfo){
if(((AppInfo) info).intent.getComponent().getPackageName().equals("com.android.deskclock")){
info.iconBitmap = Utilities.createClockIconBitmap(getContext());
}
}
FastBitmapDrawable iconDrawable = mLauncher.createIconDrawable(info.iconBitmap);
if (info.isDisabled()) {
iconDrawable.setState(FastBitmapDrawable.State.DISABLED);
}
setIcon(iconDrawable, mIconSize);
setText(info.title);
if (info.contentDescription != null) {
setContentDescription(info.contentDescription);
}
// We don't need to check the info since it's not a ShortcutInfo
super.setTag(info);
// Verify high res immediately
verifyHighRes();
}