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 ...
随机推荐
- Probability theory
1.Probability mass functions (pmf) and Probability density functions (pdf) pmf 和 pdf 类似,但不同之处在于所适用的分 ...
- c语言题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点
//题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小.也可能没有鞍点. // #include "stdio.h" #include <stdli ...
- openssl编译(VC6.0)
官网:http://www.openssl.org/ 得到源码: git clone https://github.com/openssl/openssl 一.用vc编译器编译: 1.下载nasm: ...
- 运用JavaScript构建你的第一个Metro式应用程序(onWindows 8)(三)
原文 http://blog.csdn.net/zhangxin09/article/details/6793593 这是<运用 JavaScript构建你的第一个Metro式应用程序>系 ...
- Referrer 还是 Referer?
上回我写了一篇文章介绍「Referrer Policy」,有小伙伴看完后问我:Referrer 这个单词到底怎么拼,为什么有时候中间有两个 r,有时候只有一个? 是的,这是一个很有趣的问题,这里就给有 ...
- 转:web前端面试题合集 (Javascript相关)(js异步加载详解)
1. HTTP协议的状态消息都有哪些? 1**:请求收到,继续处理2**:操作成功收到,分析.接受3**:完成此请求必须进一步处理4**:请求包含一个错误语法或不能完成5**:服务器执行一个完全有效请 ...
- 一步一步挖出Compute
前几天在做结账的时候,对数据表DataGridView控件的单列求和纠结了一番. 如今差点儿养成了习惯,对于一些东西疏于開始的思考,不会先想到百度,这里我是先想到了第一版的机房收费那块的 ...
- HTML5中video的使用一
<!DOCTYPE html> <html> <head> <title>HTML5 </title> <meta http-equi ...
- 从文档流来看内联元素和块元素的css排版
veda原创[抄录]讲得很好存自己这里看 从文档流来看内联元素和块元素的css排版 CSS文档流与块级元素(block).内联元素(inline),之前翻阅不少书籍,看过不少文章, 看到所多的是零碎的 ...
- Nutch
nutch 插件开发[资料整理]:http://my.oschina.net/cloudcoder/blog/472915 Nutch2.3+Mongodb+ElasticSearch:http:// ...