首页 > 代码库 > android launcher 日历图标显示日期

android launcher 日历图标显示日期

看到iphone上的日历图标上的数字会随着日期的变化而变化,最近在android平台上也研究了 一下,实现方法如下:

直接上源码

在launcher里改的

首先,在IconCache.java文件中,找到方法private CacheEntry cacheLocked(ComponentName componentName, ResolveInfo info,
            HashMap<Object, CharSequence> labelCache)
在entry.icon = Utilities.createIconBitmap(icon, mContext); 这个位置修改:

<span style="font-size:14px;">if(info.activityInfo.packageName.equals("com.android.calendar")){
                entry.icon = Utilities.createCalendarIconBitmap(icon, mContext);
            }else{
                if (index >= 0) {
                    entry.icon = Utilities.createIconBitmap(icon, mContext);
                } else {
                    entry.icon = Utilities.createIconBitmap(
                            /* SPRD: Feature 253522, Remove the application drawer view @{ */
                            // getFullResIcon(info), mContext);
                        icon, mContext, true);
                }
            }</span>


改后源码如下:

<span style="font-size:14px;">private CacheEntry cacheLocked(ComponentName componentName, ResolveInfo info,
            HashMap<Object, CharSequence> labelCache) {
        CacheEntry entry = mCache.get(componentName);
        if (entry == null) {
            entry = new CacheEntry();

            mCache.put(componentName, entry);

            ComponentName key = LauncherModel.getComponentNameFromResolveInfo(info);
            if (labelCache != null && labelCache.containsKey(key)) {
                entry.title = labelCache.get(key).toString();
            } else {
                entry.title = info.loadLabel(mPackageManager).toString();
                if (labelCache != null) {
                    labelCache.put(key, entry.title);
                }
            }
            if (entry.title == null) {
                entry.title = info.activityInfo.name;
            }

             /* SPRD: Fix bug 281291, remove icon_top for theme defaut icon @{ */
            /* SPRD: UUI theme : system icons @{ */
            Drawable icon;
            /* SPRD: Fix bug294355, add just to ThemeManager. @{ */
            int index = sysIndexOf(componentName.getClassName());
            Log.i("jxt", "index:"+index+",Name:"+componentName.getClassName());
            icon = getFullResIcon(info);

//changed by  leo 
            if(info.activityInfo.packageName.equals("com.android.calendar")){
                entry.icon = Utilities.createCalendarIconBitmap(icon, mContext);
            }else{
                if (index >= 0) {
                    entry.icon = Utilities.createIconBitmap(icon, mContext);
                } else {
                    entry.icon = Utilities.createIconBitmap(
                            /* SPRD: Feature 253522, Remove the application drawer view @{ */
                            // getFullResIcon(info), mContext);
                        icon, mContext, true);
                }
            }
            /* @} */
            /* @} */

            /* @} */
        }
        return entry;
    }</span>

接下来修改Utilities.java

添加一个函数:


<span style="font-size:14px;">static Bitmap createCalendarIconBitmap(Drawable icon, Context context){
        Bitmap calendarIcon = createIconBitmap(icon,context);
        String dayString  = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
        
        synchronized (sCanvas) {
            final Canvas canvas = sCanvas;
            canvas.setBitmap(calendarIcon);
            
            final float mDensity = context.getResources().getDisplayMetrics().density;
            
            Paint mDatePaint = new Paint();
            mDatePaint.setTypeface(Typeface.DEFAULT_BOLD);
            mDatePaint.setTextSize((int)30F * mDensity);
            mDatePaint.setColor(0xff000000);
            mDatePaint.setAntiAlias(true);

            Rect rect = new Rect();
            mDatePaint.getTextBounds(dayString,0,dayString.length(),rect);
            int hoffset = 20;
            int width1 = rect.right - rect.left;
            int height1 = rect.bottom - rect.top;
            int width2 = calendarIcon.getWidth();
            int height2 = calendarIcon.getHeight() + hoffset;
            
            canvas.drawText(dayString,(width2 - width1)/2 - rect.left,(height2 - height1)/2 - rect.top,mDatePaint);
            
            canvas.setBitmap(null);
            return calendarIcon;
        }
    }</span>
再修改LauncherModel.java文件:

在onReceive()方法中添加如下代码:

<span style="font-size:14px;">//changed by leo
        }else if(Intent.ACTION_DATE_CHANGED.equals(action) ||
                Intent.ACTION_TIME_CHANGED.equals(action) ||
                Intent.ACTION_TIMEZONE_CHANGED.equals(action)){
            final String packageName = "com.android.calendar";
            enqueuePackageUpdated(new PackageUpdatedTask(
                    PackageUpdatedTask.OP_UPDATE, new String[]{packageName}));
        }</span>
最后修改LauncherApplication.java文件,如果是launcher3的源码,则修改LauncherAppState.java文件

我这里修改的是

LauncherAppState.java

在构造函数 private LauncherAppState()中添加:

<span style="font-size:14px;"> //changed by leo
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_DATE_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);</span>

修改后的样式为:

<span style="font-size:14px;"> // Register intent receivers
        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addDataScheme("package");
        sContext.registerReceiver(mModel, filter);
        filter = new IntentFilter();
        filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
        filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
        filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
 //changed by leo
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_DATE_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        
        sContext.registerReceiver(mModel, filter);
</span>
当然, 这样是不能运行看到效果的,要将该导入的包都导入 ,然后再单编译launcher模块,push到手机里,就能看到日历图标上显示当前日期了。