动态修改桌面应用图标

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();
}

你可能感兴趣的:(launcher3)