Android 类似未读短信图标显示数字效果的分析
之前一直以为是应用本身在对图标进行修改,看了源码之后发现其实主要的工作并不是应用自己完成的,主要的工作在是launcher里面完成的.


- //状态
- 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";
- /** 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接收到应用发送的广播,进行判断改应用是否可以显示有未处理事件的图标)
- 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注册对应的广播接收器)
- 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(处理应用的图标显示未处理事件的数字)
- 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(配置哪些应用可以显示待处理的事件)

- <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 类似未读短信图标显示数字效果的分析的更多相关文章
- Android中为图标加上数字--用于未读短信数提醒,待更新应用数提醒等
本文属于原创,转载请著名出处:http://flysnow.iteye.com/blog/906770 写道 在我们开发一些如短消息.应用商店等应用时,会考虑在短消息的图标上加上未读短信的数量,在应用 ...
- android: 接收和发送短信
8.2 接收和发送短信 收发短信应该是每个手机最基本的功能之一了,即使是许多年前的老手机也都会具备这 项功能,而 Android 作为出色的智能手机操作系统,自然也少不了在这方面的支持.每个 A ...
- 解决:HotSeat短信图标提醒有误
[操作步骤]正常收发短信.彩信. [测试结果]所有短信均已阅读,但在HOME界面的短信图标仍提示有一条短信未读.重启后仍存在. 经过分析,导致该情况的主要原因为当彩信已读的时候,launcher中进行 ...
- 向android模拟器打电话发短信的简单方法
在开发android应用程序时,有时候需要测试一下向android手机拨打电话发送短信时该应用程序的反应.譬如编写一个广播接收器,来提示用户有短信收到或者处理短信,就需要向该手机发送短信来进行测试.这 ...
- Android监听系统短信数据库变化-提取短信内容
由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...
- Android学习笔记之短信验证码的获取和读取
PS:最近很多事情都拖拖拉拉的..都什么办事效率啊!!! 还得吐槽一下移动运营商,验证码超过五次的时候,直接把我的手机号封闭.真是受够了. 学习笔记: 1.Android之如何获取短信验证码. 2.如 ...
- android打电话、发短信实现
打电话: Intent intent = newIntent(Intent.ACTION_CALL,Uri.parse("tel:"+"156666666666" ...
- Android开发之发送短信
本实例通过SmsManager的sendTextMessage方法实现发送短信关于SmsManager的具体解释大家能够參照:Android开发之SmsManager具体解释 实例执行效果图: 程序代 ...
- Android下调用收发短信邮件等
Android下调用收发短信邮件等 1,调web浏览器Uri myBlogUri = Uri.parse("http://xxxxx.com");returnIt = new In ...
随机推荐
- 搞了一个独立博客,请各位光临pingworld.cn
嘿嘿,每次在一个大网站上建立自己的博客后总是没有动力持续更新下去,回想其原因很大是因为没有一个自己的地盘,懒得维护!还有一个原因就是自己也没有什么干货值得跟大家分享. 随着工作的时日见长,有了各种各样 ...
- MapReduce ---- TD-IDF
1.TF-IDF TF-IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明.描述单个term与特定document的相关 ...
- Cocos2d-x 学习之路------(CCCallfunc 系列)
CCCallFunc,CCCallFuncN,CCCallFuncND,CCCallFuncO类都是调用函数来执行动作,他们的使用只是局限于他们调用的的函数的参数不同而不同 CCCallFunc的回调 ...
- Telnet RFC
http://tools.ietf.org/html/rfc857 http://www.faqs.org/rfcs/rfc854.html 不错: http://blog.csdn.net/chao ...
- ICON图标文件解析
icon是一种图标格式,用于系统图标.软件图标等,这种图标扩展名为*.icon.*.ico.常见的软件或windows桌面上的那些图标一般都是ICON格式的. ICON文件格式比较简单,包含文件头段. ...
- shell脚本中常见的一些特殊符号和作用详解
这篇文章主要介绍了shell脚本中常见的一些特殊符号和它的作用详解,总结的很简洁,容易看懂,需要的朋友可以参考下 在编写Shell脚本时,我们需要会用到各种各样的特殊符号,通过这些特殊符号可以使我 ...
- NOI2015 Day2
NOI2015 Day2 荷马史诗 题目描述:给出\(n\)个数,要求\(n\)个\(k\)进制数来对应这\(k\)个数(允许有前导零),\(n\)个\(k\)进制数互不为前缀,求\(n\)个数乘以对 ...
- Effective Objective-C 读书笔记
一本不错的书,给出了52条建议来优化程序的性能,对初学者有不错的指导作用,但是对高级阶段的程序员可能帮助不是很大.这里贴出部分笔记: 第2条: 使用#improt导入头文件会把头文件的内容全部暴露到目 ...
- Alisha’s Party(队列)
Alisha’s Party Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- libcurl使用示例
远程下载文件,并将http 头信息存放内存中以及文件大小等相关信息: #include <stdio.h> #include <curl/curl.h> #include &l ...