之前一直以为是应用本身在对图标进行修改,看了源码之后发现其实主要的工作并不是应用自己完成的,主要的工作在是launcher里面完成的.

关于系统里面类似未读短信的具体处理流程如下:

原理

一个应用要实现这个效果,就要在自己有未读的消息的时候发送一个广播告诉系统我有未处理的事件了(例如:短信,电话和邮件等),同时将相关的信息进行保存,比如应用的名称(这里指的是ComponentName)和未处理事件的数量.系统将提升用户有待处理的事件交给Launcher去处理,launcher会接收到对应的广播,不是随便一个应用都有这个待遇的,launcher接到广播之后会先解析数据,看当前的应用有没有这个待遇也就是是否支持显示这个待处理事件的通知.如果通过launcher就会调用相关方法去重绘应用的icon.
效果图:

实现过程分析

Intent.java(系统增加3个常量)
frameworks/base/core/java/android/content/Intent.java
//状态
public static final String MTK_ACTION_UNREAD_CHANGED = "com.mediatek.action.UNREAD_CHANGED";
//应用名称
public static final String MTK_EXTRA_UNREAD_COMPONENT = "com.mediatek.intent.extra.UNREAD_COMPONENT";
//数量
public static final String MTK_EXTRA_UNREAD_NUMBER = "com.mediatek.intent.extra.UNREAD_NUMBER";
系统里面有这个功能几个应用相关的代码路径
日历 packages/apps/Calendar/src/com/mediatek/calendar/MTKUtils.java
邮件 :packages/apps/Email/src/com/android/email/NotificationController.java
电话 :packages/providers/ContactsProvider/src/com/android/providers/contacts/CallLogProvider.java  
短信 :packages/providers/TelephonyProvider/src/com/android/providers/telephony/MmsSmsProvider.java
 
这里以电话为例:
假设当前有人打电话进来,系统会保存改记录到数据库,根据事件是否已经处理来判断是否发送广播
 
CallLogProvider.java(发送有待处理事件的广播)
packages/providers/ContactsProvider/src/com/android/providers/contacts/CallLogProvider.java
/** M: send new Calls broadcast to luancher to update unread icon @{ */public static final void notifyNewCallsCount(SQLiteDatabase db, Context context) {Cursor c = null;…..//send count=0 to clear the unread iconif (newCallsCount >= 0) { //有新的来电数量Intent newIntent = new Intent(Intent.MTK_ACTION_UNREAD_CHANGED);newIntent.putExtra(Intent.MTK_EXTRA_UNREAD_NUMBER, newCallsCount);newIntent.putExtra(Intent.MTK_EXTRA_UNREAD_COMPONENT, new ComponentName(Constants.CONTACTS_PACKAGE,Constants.CONTACTS_DIALTACTS_ACTIVITY));context.sendBroadcast(newIntent); //发送对应的广播android.provider.Settings.System.putInt(context.getContentResolver(), Constants.CONTACTS_UNREAD_KEY, Integer.valueOf(newCallsCount));}}

LauncherApplication.java(Launcher注册对应的广播接收器)

packages/apps/Launcher2/src/com/android/launcher2/LauncherApplication.java
public void onCreate() {......../// M: register unread broadcast.if (FeatureOption.MTK_LAUNCHER_UNREAD_SUPPORT) {mUnreadLoader = new MTKUnreadLoader(getApplicationContext());// Register unread change broadcast.filter = new IntentFilter();filter.addAction(Intent.MTK_ACTION_UNREAD_CHANGED);registerReceiver(mUnreadLoader, filter); //注册对应的广播接收器}..............}

MTKUnreadLoader.java(处理应用的图标显示未处理事件的数字)

packages/apps/Launcher2/src/com/android/launcher2/MTKUnreadLoader.java
static void drawUnreadEventIfNeed(Canvas canvas, View icon) {ItemInfo info = (ItemInfo)icon.getTag();if (info != null && info.unreadNum > 0) { //判断未处理事件数量Resources res = icon.getContext().getResources();..........if (info.unreadNum > Launcher.MAX_UNREAD_COUNT) {unreadTextNumber = String.valueOf(Launcher.MAX_UNREAD_COUNT);unreadTextPlusPaint.getTextBounds(unreadTextPlus, 0, unreadTextPlus.length(), unreadTextPlusBounds);} else {unreadTextNumber = String.valueOf(info.unreadNum);}unreadTextNumberPaint.getTextBounds(unreadTextNumber, 0, unreadTextNumber.length(), unreadTextNumberBounds);int textHeight = unreadTextNumberBounds.height();int textWidth = unreadTextNumberBounds.width() + unreadTextPlusBounds.width();// 数字的背景图NinePatchDrawable unreadBgNinePatchDrawable = (NinePatchDrawable)res.getDrawable(R.drawable.ic_newevents_numberindication);.........Rect unreadBgBounds = new Rect(0, 0, unreadBgWidth, unreadBgHeight);unreadBgNinePatchDrawable.setBounds(unreadBgBounds);int unreadMarginTop = 0;int unreadMarginRight = 0;if (info instanceof ShortcutInfo) { //workspace 里面的快捷方式if (info.container == (long)LauncherSettings.Favorites.CONTAINER_HOTSEAT) {unreadMarginTop = (int)res.getDimension(R.dimen.hotseat_unread_margin_top);unreadMarginRight = (int)res.getDimension(R.dimen.hotseat_unread_margin_right);} else if (info.container == (long)LauncherSettings.Favorites.CONTAINER_DESKTOP) {unreadMarginTop = (int)res.getDimension(R.dimen.workspace_unread_margin_top);unreadMarginRight = (int)res.getDimension(R.dimen.workspace_unread_margin_right);} else {unreadMarginTop = (int)res.getDimension(R.dimen.folder_unread_margin_top);unreadMarginRight = (int)res.getDimension(R.dimen.folder_unread_margin_right);}} else if (info instanceof FolderInfo) { //文件夹if (info.container == (long)LauncherSettings.Favorites.CONTAINER_HOTSEAT) {unreadMarginTop = (int)res.getDimension(R.dimen.hotseat_unread_margin_top);unreadMarginRight = (int)res.getDimension(R.dimen.hotseat_unread_margin_right);} else if (info.container == (long)LauncherSettings.Favorites.CONTAINER_DESKTOP) {unreadMarginTop = (int)res.getDimension(R.dimen.workspace_unread_margin_top);unreadMarginRight = (int)res.getDimension(R.dimen.workspace_unread_margin_right);}}else if (info instanceof ApplicationInfo) { //all app 里面的应用iconunreadMarginTop = (int)res.getDimension(R.dimen.app_list_unread_margin_top);unreadMarginRight = (int)res.getDimension(R.dimen.app_list_unread_margin_right);}int unreadBgPosX = icon.getScrollX() + icon.getWidth() - unreadBgWidth - unreadMarginRight;int unreadBgPosY = icon.getScrollY() + unreadMarginTop;canvas.save();canvas.translate(unreadBgPosX, unreadBgPosY);unreadBgNinePatchDrawable.draw(canvas);/// M: Draw unread text.Paint.FontMetrics fontMetrics = unreadTextNumberPaint.getFontMetrics();if (info.unreadNum > Launcher.MAX_UNREAD_COUNT) {canvas.drawText(unreadTextNumber,(unreadBgWidth - unreadTextPlusBounds.width()) / 2,(unreadBgHeight + textHeight) / 2,unreadTextNumberPaint);canvas.drawText(unreadTextPlus,(unreadBgWidth + unreadTextNumberBounds.width()) / 2,(unreadBgHeight + textHeight) / 2 + fontMetrics.ascent / 2,unreadTextPlusPaint);} else {.....}}

unread_support_shortcuts.xml(配置哪些应用可以显示待处理的事件)

packages/apps/Launcher2/res/xml/unread_support_shortcuts.xml
<unreadshortcuts xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
<!--电话--><shortcutlauncher:unreadPackageName="com.android.contacts"launcher:unreadClassName="com.android.contacts.activities.DialtactsActivity"launcher:unreadType="0"launcher:unreadKey="com_android_contacts_mtk_unread"/>
<!--短信--><shortcutlauncher:unreadPackageName="com.android.mms"launcher:unreadClassName="com.android.mms.ui.BootActivity"launcher:unreadType="0"launcher:unreadKey="com_android_mms_mtk_unread"/>
<!--邮件--><shortcutlauncher:unreadPackageName="com.android.email"launcher:unreadClassName="com.android.email.activity.Welcome"launcher:unreadType="0"launcher:unreadKey="com_android_email_mtk_unread"/>................
</unreadshortcuts>

原文:http://862123204-qq-com.iteye.com/blog/2000310

Android Launcher桌面图标显示数字相关推荐

  1. android 为桌面图标添加数字角标

    android 为桌面图标添加数字角标 我的github项目 BadgeForAppIcon 看完麻烦 star 一下 在某些app的设计中,产品经理总会想当然的提出为桌面图标添加数字角标的需求.作为 ...

  2. android launcher 日历图标显示日期

    看到iphone上的日历图标上的数字会随着日期的变化而变化,最近在android平台上也研究了 一下,实现方法如下: 直接上源码 在launcher里改的 首先,在IconCache.java文件中, ...

  3. Android 桌面图标右上角数字

    在Android原生系统中,不支持桌面图标显示,未读消息提醒的数字 详情参考:http://m.2cto.com/kf/201607/532158.html 一些强大的手机厂商(小米,三星,索尼)提供 ...

  4. 创建android studio桌面图标

    创建android studio桌面图标  1. 用root权限创建/usr/share/applications/studio.desktop  然后我们要在这个文件里面下如下代码: [Deskto ...

  5. windows桌面图标显示白边的解决方案

    文章目录 前言 一.具体步骤 1.缩小图标 2.自动排列 总结 前言 windows桌面图标显示带有白色边框,十分影响观感,为了美观,我们采取缩小图标的方法使其消失. 一.具体步骤 1.缩小图标 右击 ...

  6. Win10桌面图标显示不正常,变为白色

    Win10桌面图标显示不正常变成了白色 问题 解决步骤 问题 开机不知道什么原因,windows 10 桌面图标极个别变成了白色,软件是可以点击正常打开使用,但是看着特别不爽.今天就告诉大家一种办法, ...

  7. win8计算机不显示视频图标,如何解决Win8.1桌面图标显示不正常的问题?

    桌面快捷方式图标出现异常是Windows系统经常出现的问题,这个很正常.最近,使用Win8.1系统的用户,在打开电脑并登陆到Win8.1 系统桌面时,发现桌面的图标显示不正常.那么,出现这种情况,该如 ...

  8. win8 桌面显示计算机图标怎么删除,win8系统桌面图标显示快捷方式箭头怎么删除...

    打开win8系统电脑发现一个奇怪现象,win8系统桌面图标显示快捷方式箭头,虽然不影响正常使用,但是看着非常奇怪,影响桌面美观.上网查找一些去除的方法,但是操作方法比较复杂.本文系统城小编向大家介绍w ...

  9. win10服务器显示图标,win10图标变白怎么办 Win10桌面图标显示不正常解决办法

    一台新的电脑,在出厂之后,我们需要先对它装系统,装好系统之后,我们只需要在电脑上安装软件便可以使用了,安装的软件可以将快捷方式发送到桌面,但是有时候我们发现,这个快捷方式却无法显示缩略图,但是也可以使 ...

最新文章

  1. CUDA功能和通用功能
  2. 潦草字体在线识别_小学生“狂草”字体走红,字迹凌乱老师认不出,网友:谁翻译一下...
  3. CentOS 6.0 系统 LAMP(Apache+MySQL+PHP)安装步骤
  4. Python基础教程(四):循环语句
  5. [云炬学英语]每日一句2020.9.3
  6. c语言指针如何增加内存大小,C语言如何给指针分配内存?
  7. 调和分析笔记1|极大函数法及简单应用
  8. 开源分布式关系型数据库 PingCAP 完成 B 轮融资
  9. NE555定时器 学习 之 初步了解555
  10. Android模拟器中实现音、视频文件的断点播放
  11. ISP模块之色彩增强算法--HSV空间Saturation通道调整
  12. 31.Python中verbatim标签使用详解
  13. 解决——zip压缩包解压后的文件全是乱码问题
  14. JSP起源、JSP的运行原理、JSP的执行过程
  15. 135编辑器如何插入文件
  16. 解决:ClassCastException: org.springframework.util.LinkedCaseInsensi
  17. UML建模(二):基于UML的软件开发过程
  18. 怎样在知网下载PDF版本的硕博士论文
  19. 大一学生HTML期末作业 【html体育排球5页面带注册】学生网页设计作业源码
  20. excel表计算机实践操作,Excel电子表格计算机实践任务书

热门文章

  1. iOS 绘图(drawrect)图片裁剪的红色框框
  2. 应付款与分工之利读后感
  3. 从零搭建 SpringCloud 服务
  4. 华三系统服务器网卡,01-第1章 H3C自研网卡功能及运行环境简介
  5. 数字拼图java小程序_JS写的数字拼图小游戏代码[学习参考]
  6. 计算机关系差 并 交,计算机三个关系投影 交 并 差是什么意思
  7. javaweb练手项目jsp+servlet简易购物车系统
  8. 【记录】螺纹连接与螺旋传动
  9. 回炉篇5—数据结构(4)之冒泡、选择、插入排序算法
  10. Chrome源码剖析