Launcher 3カレンダーアイコンは、日付の変更に従って変更されます.

6875 ワード

前回の記事ではダイナミッククロックとダイナミックカレンダーのLauncherアイコンを実現しましたが、今日のテストでダイナミックカレンダーにleakreceivedの問題があり、Receivedのバインドをキャンセルできないことがわかりました.そこで、今日はダイナミックカレンダーアイコンを別の方法で実装します.
LauncherAppState.JAvaに追加:
public static final String ACTION_UPDATE_ICON = "com.xxx.update_icon";
 
private LauncherAppState() {
    …………
            // UPDATE APPICON BEGIN
        IntentFilter timefilter = new IntentFilter();
        timefilter.addAction(Intent.ACTION_DATE_CHANGED);
        timefilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        timefilter.addAction("android.intent.action.TIME_SET");
        timefilter.addAction(ACTION_UPDATE_ICON);
        sContext.registerReceiver(mModel, timefilter);
        // UPDATE APPICON END
}

LauncherModel.JAvaに追加:
public interface Callbacks {
        …………
        public void updateAppIcon(AppInfo info);   //UPDATE APPICON
}
 @Override
    public void onReceive(Context context, Intent intent) {
        …………
     /**************UPDATE APPICON BEGIN **********************************/
       else if (Intent.ACTION_DATE_CHANGED.equals(action) ||
            Intent.ACTION_TIMEZONE_CHANGED.equals(action) ||
            "android.intent.action.TIME_SET".equals(action) ||
            LauncherAppState.ACTION_UPDATE_ICON.equals(action)) {
	        String pkgName = null;
	        if (LauncherAppState.ACTION_UPDATE_ICON.equals(action)) {
	            pkgName = intent.getStringExtra("packageName");
	        } else {
	            pkgName = "com.android.calendar";
	        }
	
	        final ArrayList<AppInfo> list
	                = (ArrayList<AppInfo>) mBgAllAppsList.data.clone();
	
	        if (null == list || list.isEmpty()) {
	            return;
	        }
	
	        AppInfo info = null;
	        for (AppInfo ai : list) {
	            if (ai.componentName.getPackageName().equals(pkgName)) {
	                info = ai;
	                break;
	            }
	        }
	
	        if (null != info && mCallbacks != null) {
	            Callbacks callbacks = mCallbacks.get();
	            if (callbacks != null && info != null) {
	                callbacks.updateAppIcon(info);
	            }
	        }
        }
        /**************UPDATE APPICON END *****************************/
}

Launcher.JAvaに追加:
    // UPDATE APPICON BEGIN
    @Override
    public void updateAppIcon(AppInfo info){
        if (null != mIconCache) {
//        	mIconCache.updateTitleAndIcon(info);
        	mWorkspace.updateShortcut(info.componentName.getPackageName());
        }
    }
    // UPDATE APPICON END

Workspace.JAvaに追加:
 // UPDATE APPICON BEGIN
    void updateShortcut(String pkgName) {
        ArrayList<ShortcutAndWidgetContainer> childrenLayouts = getAllShortcutAndWidgetContainers();
        for (ShortcutAndWidgetContainer layout: childrenLayouts) {
            int childCount = layout.getChildCount();
            for (int j = 0; j < childCount; j++) {
                final View view = layout.getChildAt(j);
                Object tag = view.getTag();
                if (tag instanceof ShortcutInfo) {
                    ShortcutInfo info = (ShortcutInfo) tag;
                    try {
                        if (pkgName.equals(info.intent.getComponent().getPackageName())) {
                            BubbleTextView bv = (BubbleTextView) view;
//                            bv.applyFromShortcutInfo(info, mIconCache);
                            bv.applyCalendarInfo(info);
                        	bv.invalidate();
                        }
                    } catch (Exception e) {
                    }
                }
            }
        }
    }
    // UPDATE APPICON END
BubbleTextView.JAvaに追加:
    /************************UPDATE APPICON start*****************************/
    public void applyCalendarInfo(ShortcutInfo info) {
        Bitmap b = Utilities.createCalendarIconBitmap(mLauncher);

        FastBitmapDrawable iconDrawable = mLauncher.createIconDrawable(b);
        iconDrawable.setGhostModeEnabled(info.isDisabled != 0);

        setIcon(iconDrawable, mIconSize);
        if (info.contentDescription != null) {
            setContentDescription(info.contentDescription);
        }
        setText(info.title);
        setTag(info);

//        if (promiseStateChanged || info.isPromise()) {
//            applyState(promiseStateChanged);
//        }
    }
   
    /************************UPDATE APPICON end*****************************/

Utilities.JAvaに追加:
	//UPDATE APPICON
	static Bitmap createCalendarIconBitmap(Context context) {
		//Time time = new Time();
		//time.setToNow();  
		int dayOfMonth         = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
		int dayOfWeek          = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
//      canvas.drawBitmap(getRes(mTime.monthDay), null, getBounds(), mPaint);  
		Bitmap calendarBackground = BitmapFactory.decodeResource(context.getResources(), R.drawable.calendar);
		Bitmap dayOfMonthRes      = getCalendarDataRes(context, dayOfMonth);
		Bitmap dayOfWeekRes       = getCalendarWeekDayRes(context, dayOfWeek);
		
		int width  = getIconBitmapSize();
		int height = getIconBitmapSize();
		
		Bitmap newBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(newBmp);
		
		Rect destRect = new Rect(0, 0, width, height);
		Rect srcRect  = new Rect(0, 0, calendarBackground.getWidth(), calendarBackground.getHeight());
		
		canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));
		canvas.drawBitmap(calendarBackground, srcRect, destRect, null);
		canvas.drawBitmap(dayOfMonthRes, (width - dayOfMonthRes.getWidth()) / 2 , (height - dayOfMonthRes.getHeight()) / 2 + 10, null);
		canvas.drawBitmap(dayOfWeekRes, (width - dayOfWeekRes.getWidth()) / 2, dayOfWeekRes.getHeight(), null);
		
		canvas.save(Canvas.ALL_SAVE_FLAG);
		canvas.restore();
		
		return newBmp;
	}	
</pre><pre>
IconCache.JAvaに追加:
 private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,
            UserHandleCompat user, boolean usePackageIcon, boolean useLowResIcon) {
          …………
        //UPDATE APPICON BEGIN
        if (null != entry && componentName.getPackageName().equals("com.android.calendar")) {
             entry.icon = Utilities.createCalendarIconBitmap(mContext);
        }
        //UPDATE APPICON END
        return entry;
}

面倒そうに見えたが、放送受信機からログアウトできなかったerrorが報告された.