这里面主要的工作在是launcher里面完成的.
关于系统里面类似未读短信的具体处理流程如下,

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

实现过程分析
Intent.java(系统增加3个常量)
frameworks/base/core/java/android/content/Intent.java
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
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 icon
if (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));
}
}
MTKUnreadLoader.java(Launcher接收到应用发送的广播,进行判断改应用是否可以显示有未处理事件的图标)
packages/apps/Launcher2/src/com/android/launcher2/MTKUnreadLoader.java
Java代码 收藏代码
public void onReceive(final Context context, final Intent intent) {
final String action = intent.getAction();
//过滤广播
if (Intent.MTK_ACTION_UNREAD_CHANGED.equals(action)) {
final ComponentName componentName = (ComponentName) intent.getExtra(Intent.MTK_EXTRA_UNREAD_COMPONENT);
final int unreadNum = intent.getIntExtra(Intent.MTK_EXTRA_UNREAD_NUMBER, -1);

        if (mCallbacks != null && componentName != null && unreadNum != -1) {  //判断是否支持该功能  final int index = supportUnreadFeature(componentName);  if (index >= 0) { //支持  boolean ret = setUnreadNumberAt(index, unreadNum);  if (ret) {  final UnreadCallbacks callbacks = mCallbacks.get();  if (callbacks != null) {  callbacks.bindComponentUnreadChanged(componentName, unreadNum);  }  .........
}

LauncherApplication.java(Launcher注册对应的广播接收器)
packages/apps/Launcher2/src/com/android/launcher2/LauncherApplication.java
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
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 里面的应用icon  unreadMarginTop = (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
Xml代码

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

Android 类似未读短信消息图标显示的实现分析相关推荐

  1. Android 类似未读短信图标显示数字效果的分析

     之前一直以为是应用本身在对图标进行修改,看了源码之后发现其实主要的工作并不是应用自己完成的,主要的工作在是launcher里面完成的. 关于系统里面类似未读短信的具体处理流程如下,   原理 一个应 ...

  2. 求android实现未读短信图标数字提示效果

    ============问题描述============ 大家好, 我现在碰到一个需求是在一个图标上面加上一个数字,来提示有未读短信之类的效果. 效果图片发不出来,不知道是不是CSDN不让发,有知道的 ...

  3. android查询未读短信,Android实现获取未接来电和未读短信数量的方法

    本文实例展示了Android实现获取未接来电和未读短信数量的方法,在Android程序开发中非常常见,是非常实用的功能,现分享给大家供大家参考.具体如下: 一.未读短信 首先注册Observer,当有 ...

  4. Android 10.0 Launcher3 电话和短信app图标显示未读短信和未接来电的条数

    最近客户有需求要求在电话app图标显示未接来电的条数 在短信app图标上显示未读信息的条数 根据需求首选要在Launcher3的Launcher.java中,启动launcher时,查询未读短信和未接 ...

  5. Android 11.0 12.0Launcher3 电话和短信app图标显示未读短信和未接来电的条数

    在11.0 12.0产品开发中,最近客户有需求要求在电话app图标显示未接来电的条数 在短信app图标上显示未读信息的条数 根据需求首选要在Launcher3的Launcher.java中,启动lau ...

  6. Android 12.0Launcher3 电话和短信app图标显示未读短信和未接来电的条数

    1.概述 在12.0产品开发中,最近客户有需求要求在电话app图标显示未接来电的条数 在短信app图标上显示未读信息的条数 根据需求首选要在Launcher3的Launcher.java中,启动lau ...

  7. android开发笔记之锁屏界面未读短信未接来电提醒(android 4.4)

    客户需求 最近在做一个项目,android 4.4系统,客户要求在锁屏界面有未读短信未接来电的提醒功能.而平台没有此功能,要自己实现.并且时间非常紧,---.(其实软件工程师基本上都是这样,坑,坑,坑 ...

  8. Android实现获取未接来电和未读短信数量的方法

    项目开发需要 要求获取未接来电和未读短信的数量 1.未接来电的获取方式 通过广播com.android.phone.NotificationMgr.MissedCall_intent 接收像在锁屏界面 ...

  9. Android Launcher界面未接来电和未读短信条数的显示

    一 分析步骤和过程 我们需要实现的是当有一个未接来电和未读短信时,Launcher界面的Dialer和Msm的icon能够显示未读条数,其实和微信的差不多.里面有一个功能就是显示未读新闻的条数 步入正 ...

最新文章

  1. SPOJ LCS Longest Common Substring
  2. 推荐一个Android开源项目-AisenWeiBo
  3. 树莓派4视频输出接口_树莓派第四代来啦!4G内存、支持双屏4K输出和H265硬解
  4. Java扑克牌(多线程)
  5. verilog中timescale
  6. SQL Server timeout分析和总结
  7. Kubernetes系列之Helm介绍篇
  8. eclipse使用python_【转】使用Python的IDE:Eclipse+PyDev
  9. 如何查看linux的版本?
  10. c语言系统关键词有哪些,C语言的那些关键字
  11. 如何向某网址Post信息,并得到CookieContainer以便以后直接通过验证
  12. openssl做HMAC实例(C++)
  13. 20191203每日一句
  14. Visual Studio介绍及安装
  15. 迅手系统连接不到服务器,逆火快速上手.doc
  16. 你看我像不像学HTML的人(五)——链接标签、注释和特殊字符
  17. Unable to open shape_predictor_68_face_landmarks.dat
  18. 在Redhat9上安装Oracle 9.2
  19. C盘爆满上热搜,简单几招释放几十G空间,一下子就不红了
  20. 性能服务器电路,【干货分享】服务器Power电路设计(上)

热门文章

  1. Java工具-根据出生年月日计算出年龄
  2. 【Vue3 第十四章】父子组件通信
  3. 大家都在学Python,你和别人的差距在哪?
  4. 年薪40W+,2018年程序员如何跳出35岁“失业”怪圈?
  5. Romax Nexus—机电一体传动系统设计与仿真平台
  6. python编程趣味试题_Python趣味编程-中国大学mooc-试题题目及答案
  7. 安装ubantu-----服务器开发之路1
  8. 读论文-OVSeg-基于遮罩自适应CLIP的开放词汇语义分割-Open-vicabulr semantic segmentation with mask-adaptived CLIP
  9. 骨传导耳机有什么优缺点,骨传导耳机好用吗
  10. 2020德勤面试开始了吗_四大2020年春招时间曝光!