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 ...
随机推荐
- 51cto那些技术专题们
Nginx配置与应用详解 UML(Unified Modeling Language,统一建模语言) 架构师的成长历程 python python book ruby html5 不可不知的Linux ...
- Oracle EBS-SQL (BOM-1):检查供应类型错误.sql
--检查供应类型错误 SELECT MSI.SEGMENT1 物料编码, MSI.DESCRIPTION 物料描述, DECODE(MSI.WIP ...
- iOS开发之主题皮肤
iOS开发之主题皮肤 分类: [iOS] 最近在开发一款[公交应用],里面有个模块涉及到主题设置,这篇文章主要谈一下个人的做法. 大概的步骤如下: (1):整个应用依赖于一个主题管理器,主题管理器根 ...
- 弹飞DZY(思维,打表,还没过全,先放着)
弹飞DZYDescription某天,机智的ZZC发明了一种超级弹力装置,为了在他的朋友DZY面前显摆,他邀请DZY一起玩个游戏.游戏一开始,ZZC在地上沿着一条直线摆上n个装置,每个装置设定初始弹力 ...
- Android Navigation Drawer(导航抽屉)
Google I/O 2013 Android 更新了Support库,新版本的Support库中新加入了几个比较重要的功能. 添加 DrawerLayout 控件,支持创建 Navigation ...
- CodeForces Round #179 (295A) - Greg and Array 一个线段树做两次用
线段树的区间更新与区间求和...一颗这样的线段树用两次... 先扫描1~k...用线段树统计出每个操作执行的次数... 那么每个操作就变成了 op. l , op.r , op.c= times* ...
- Jade 报错
今天写jade的时候遇到一个问题 Invalid indentation,you can use tabs or spaces but not both问题 经过查证原来是 在jade模板中 同时存在 ...
- 蓝桥杯试题集【Java】
一.Fibonacci数列 问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. ...
- js获取当前年月日
function GetDate(){ var now = new Date(); var year = now.getFullYear(); //年var month = now.ge ...
- VS2013 快捷键乱掉如何修改回来
比如 CTRL+E+C =注释 F6=重新生成解决方案 CTRL+D+Q=运行时快速监视 工具-->选项-->环境-->键盘-->应用以下其他键盘映射方案,下拉选择 Visua ...