分享

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

 飞鹰飞龙飞天 2014-05-17
效果图:

 实现过程分析
Intent.java(系统增加3个常量)
frameworks/base/core/java/android/content/Intent.java
Java代码  收藏代码
  1. //状态     
  2. public static final String MTK_ACTION_UNREAD_CHANGED = "com.mediatek.action.UNREAD_CHANGED";  
  3. //应用名称      
  4. public static final String MTK_EXTRA_UNREAD_COMPONENT = "com.mediatek.intent.extra.UNREAD_COMPONENT";  
  5. //数量  
  6. public static final String MTK_EXTRA_UNREAD_NUMBER = "com.mediatek.intent.extra.UNREAD_NUMBER";  
  7.    
 
系统里面有这个功能几个应用相关的代码路径
日历 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代码  收藏代码
  1. /** M: send new Calls broadcast to luancher to update unread icon @{ */  
  2.     public static final void notifyNewCallsCount(SQLiteDatabase db, Context context) {  
  3.         Cursor c = null;  
  4.        …..  
  5.         //send count=0 to clear the unread icon  
  6.         if (newCallsCount >= 0) { //有新的来电数量  
  7.             Intent newIntent = new Intent(Intent.MTK_ACTION_UNREAD_CHANGED);  
  8.             newIntent.putExtra(Intent.MTK_EXTRA_UNREAD_NUMBER, newCallsCount);  
  9.             newIntent.putExtra(Intent.MTK_EXTRA_UNREAD_COMPONENT, new ComponentName(Constants.CONTACTS_PACKAGE,  
  10.                     Constants.CONTACTS_DIALTACTS_ACTIVITY));  
  11.             context.sendBroadcast(newIntent); //发送对应的广播  
  12.             android.provider.Settings.System.putInt(context.getContentResolver(), Constants.CONTACTS_UNREAD_KEY, Integer  
  13.                     .valueOf(newCallsCount));  
  14.         }  
  15.     }  
 MTKUnreadLoader.java(Launcher接收到应用发送的广播,进行判断改应用是否可以显示有未处理事件的图标)
packages/apps/Launcher2/src/com/android/launcher2/MTKUnreadLoader.java
Java代码  收藏代码
  1. public void onReceive(final Context context, final Intent intent) {  
  2.         final String action = intent.getAction();  
  3.             //过滤广播  
  4.         if (Intent.MTK_ACTION_UNREAD_CHANGED.equals(action)) {  
  5.             final ComponentName componentName = (ComponentName) intent.getExtra(Intent.MTK_EXTRA_UNREAD_COMPONENT);  
  6.             final int unreadNum = intent.getIntExtra(Intent.MTK_EXTRA_UNREAD_NUMBER, -1);  
  7.   
  8.             if (mCallbacks != null && componentName != null && unreadNum != -1) {  
  9.                 //判断是否支持该功能  
  10.                 final int index = supportUnreadFeature(componentName);  
  11.                 if (index >= 0) { //支持  
  12.                     boolean ret = setUnreadNumberAt(index, unreadNum);  
  13.                     if (ret) {  
  14.                         final UnreadCallbacks callbacks = mCallbacks.get();  
  15.                         if (callbacks != null) {  
  16.                             callbacks.bindComponentUnreadChanged(componentName, unreadNum);  
  17.                         }  
  18.                     .........  
  19.     }  
 LauncherApplication.java(Launcher注册对应的广播接收器)
packages/apps/Launcher2/src/com/android/launcher2/LauncherApplication.java
Java代码  收藏代码
  1. public void onCreate() {  
  2.        ........  
  3.         /// M: register unread broadcast.  
  4.         if (FeatureOption.MTK_LAUNCHER_UNREAD_SUPPORT) {  
  5.             mUnreadLoader = new MTKUnreadLoader(getApplicationContext());  
  6.             // Register unread change broadcast.  
  7.             filter = new IntentFilter();  
  8.             filter.addAction(Intent.MTK_ACTION_UNREAD_CHANGED);  
  9.             registerReceiver(mUnreadLoader, filter); //注册对应的广播接收器  
  10.         }  
  11.        ..............  
  12.     }  
 MTKUnreadLoader.java(处理应用的图标显示未处理事件的数字)
packages/apps/Launcher2/src/com/android/launcher2/MTKUnreadLoader.java
Java代码  收藏代码
  1. static void drawUnreadEventIfNeed(Canvas canvas, View icon) {  
  2.         ItemInfo info = (ItemInfo)icon.getTag();  
  3.         if (info != null && info.unreadNum > 0) { //判断未处理事件数量  
  4.             Resources res = icon.getContext().getResources();  
  5.            ..........  
  6.             if (info.unreadNum > Launcher.MAX_UNREAD_COUNT) {  
  7.                 unreadTextNumber = String.valueOf(Launcher.MAX_UNREAD_COUNT);  
  8.                 unreadTextPlusPaint.getTextBounds(unreadTextPlus, 0, unreadTextPlus.length(), unreadTextPlusBounds);  
  9.             } else {  
  10.                 unreadTextNumber = String.valueOf(info.unreadNum);  
  11.             }  
  12.             unreadTextNumberPaint.getTextBounds(unreadTextNumber, 0, unreadTextNumber.length(), unreadTextNumberBounds);  
  13.             int textHeight = unreadTextNumberBounds.height();  
  14.             int textWidth = unreadTextNumberBounds.width() + unreadTextPlusBounds.width();  
  15.   
  16.             // 数字的背景图  
  17.             NinePatchDrawable unreadBgNinePatchDrawable = (NinePatchDrawable)res.getDrawable(R.drawable.ic_newevents_numberindication);  
  18.            .........  
  19.             Rect unreadBgBounds = new Rect(0, 0, unreadBgWidth, unreadBgHeight);  
  20.             unreadBgNinePatchDrawable.setBounds(unreadBgBounds);  
  21.   
  22.             int unreadMarginTop = 0;  
  23.             int unreadMarginRight = 0;  
  24.             if (info instanceof ShortcutInfo) { //workspace 里面的快捷方式  
  25.                 if (info.container == (long)LauncherSettings.Favorites.CONTAINER_HOTSEAT) {  
  26.                     unreadMarginTop = (int)res.getDimension(R.dimen.hotseat_unread_margin_top);  
  27.                     unreadMarginRight = (int)res.getDimension(R.dimen.hotseat_unread_margin_right);  
  28.                 } else if (info.container == (long)LauncherSettings.Favorites.CONTAINER_DESKTOP) {  
  29.                     unreadMarginTop = (int)res.getDimension(R.dimen.workspace_unread_margin_top);  
  30.                     unreadMarginRight = (int)res.getDimension(R.dimen.workspace_unread_margin_right);  
  31.                 } else {  
  32.                     unreadMarginTop = (int)res.getDimension(R.dimen.folder_unread_margin_top);  
  33.                     unreadMarginRight = (int)res.getDimension(R.dimen.folder_unread_margin_right);  
  34.                 }  
  35.             } else if (info instanceof FolderInfo) { //文件夹  
  36.                 if (info.container == (long)LauncherSettings.Favorites.CONTAINER_HOTSEAT) {  
  37.                     unreadMarginTop = (int)res.getDimension(R.dimen.hotseat_unread_margin_top);  
  38.                     unreadMarginRight = (int)res.getDimension(R.dimen.hotseat_unread_margin_right);  
  39.                 } else if (info.container == (long)LauncherSettings.Favorites.CONTAINER_DESKTOP) {  
  40.                     unreadMarginTop = (int)res.getDimension(R.dimen.workspace_unread_margin_top);  
  41.                     unreadMarginRight = (int)res.getDimension(R.dimen.workspace_unread_margin_right);  
  42.                 }  
  43.             }  
  44.             else if (info instanceof ApplicationInfo) { //all app 里面的应用icon  
  45.                 unreadMarginTop = (int)res.getDimension(R.dimen.app_list_unread_margin_top);  
  46.                 unreadMarginRight = (int)res.getDimension(R.dimen.app_list_unread_margin_right);  
  47.             }  
  48.   
  49.             int unreadBgPosX = icon.getScrollX() + icon.getWidth() - unreadBgWidth - unreadMarginRight;  
  50.             int unreadBgPosY = icon.getScrollY() + unreadMarginTop;  
  51.   
  52.             canvas.save();  
  53.             canvas.translate(unreadBgPosX, unreadBgPosY);  
  54.   
  55.             unreadBgNinePatchDrawable.draw(canvas);  
  56.   
  57.             /// M: Draw unread text.  
  58.             Paint.FontMetrics fontMetrics = unreadTextNumberPaint.getFontMetrics();  
  59.             if (info.unreadNum > Launcher.MAX_UNREAD_COUNT) {  
  60.                 canvas.drawText(unreadTextNumber,  
  61.                                 (unreadBgWidth - unreadTextPlusBounds.width()) / 2,  
  62.                                 (unreadBgHeight + textHeight) / 2,  
  63.                                 unreadTextNumberPaint);  
  64.                 canvas.drawText(unreadTextPlus,  
  65.                                 (unreadBgWidth + unreadTextNumberBounds.width()) / 2,  
  66.                                 (unreadBgHeight + textHeight) / 2 + fontMetrics.ascent / 2,  
  67.                                 unreadTextPlusPaint);  
  68.             } else {  
  69.                .....  
  70.         }  
  71.     }  
 unread_support_shortcuts.xml(配置哪些应用可以显示待处理的事件)
packages/apps/Launcher2/res/xml/unread_support_shortcuts.xml
Xml代码  收藏代码
  1. <unreadshortcuts xmlns:launcher="http://schemas./apk/res/com.android.launcher">  
  2. <!--电话-->  
  3.     <shortcut  
  4.         launcher:unreadPackageName="com.android.contacts"  
  5.         launcher:unreadClassName="com.android.contacts.activities.DialtactsActivity"  
  6.         launcher:unreadType="0"  
  7.         launcher:unreadKey="com_android_contacts_mtk_unread"  
  8.      />  
  9. <!--短信-->  
  10.      <shortcut  
  11.         launcher:unreadPackageName="com.android.mms"  
  12.         launcher:unreadClassName="com.android.mms.ui.BootActivity"  
  13.         launcher:unreadType="0"  
  14.         launcher:unreadKey="com_android_mms_mtk_unread"  
  15.      />  
  16. <!--邮件-->  
  17.      <shortcut  
  18.         launcher:unreadPackageName="com.android.email"  
  19.         launcher:unreadClassName="com.android.email.activity.Welcome"  
  20.         launcher:unreadType="0"  
  21.         launcher:unreadKey="com_android_email_mtk_unread"  
  22.      />  
  23.     ................  
  24. </unreadshortcuts>  
 

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多