原文首发地址 Android Launcher 界面添加未接来电 / 未读短信条数显示

本文代码基于 Android 6.0(高通),原生不支持未接来电以及未读短信的图标右上角数目显示。

涉及到几个文件:

1. packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
2. packages/apps/Launcher3/src/com/android/launcher3/Utilities.java
3. packages/apps/Launcher3/AndroidManifest.xml

具体的思路:Launcher 中注册 ContentObserver 来监听短信和电话数据库,当数据发生变化时,读取读取数据库未读数目之后通过 ICON_NAME ,重新绘制短信,电话的图标(在原图右上角画圆和数字)。


具体代码:

1. Launcher.java

  • 首先是定义两个 ContentObserver
private final static int UPDATE_MMS_ICON = 826;
private final static int UPDATE_CALL_ICON = 1206;public class SMSContentObserver extends ContentObserver {private Handler mHandler;public SMSContentObserver(Context context, Handler handler) {super(handler);mHandler = handler;}@Overridepublic void onChange(boolean selfChange) {Log.i("Launcher-","SMSContentObserver onChange");mHandler.removeMessages(UPDATE_MMS_ICON);Message msg = mHandler.obtainMessage(UPDATE_MMS_ICON);msg.obj = getMissMmsCount();mHandler.sendMessage(msg);}
}public class CallContentObserver extends ContentObserver {private Handler mHandler;public CallContentObserver(Context context, Handler handler) {super(handler);mHandler = handler;}@Overridepublic void onChange(boolean selfChange) {Log.i("Launcher-","CallContentObserver onChange");mHandler.removeMessages(UPDATE_CALL_ICON);Message msg = mHandler.obtainMessage(UPDATE_CALL_ICON);msg.obj = getMissCallCount();mHandler.sendMessage(msg);}
}
  • 在 onCreate() 中注册 ContentObserver
private SMSContentObserver smsContentObserver = null;
private CallContentObserver callContentObserver = null;  smsContentObserver = new SMSContentObserver(this,mHandler);
callContentObserver =new CallContentObserver(this,mHandler);getContentResolver().registerContentObserver(Calls.CONTENT_URI,true,callContentObserver);
getContentResolver().registerContentObserver(Uri.parse("content://mms-sms/"),true,smsContentObserver);
  • 定义两个 ICON_NAME
// 这两个 ICON_NAME 根据自己实际系统短信和电话页面对应包名填写
private final static String PHONE_ICON_NAME = "com.android.dialer.DialtactsActivity";
private final static String MMS_ICON_NAME = "com.android.messaging.ui.conversationlist.ConversationListActivity";
  • mHandler 中处理
@Thunk
final Handler mHandler = new Handler(new Handler.Callback() {@Overridepublic boolean handleMessage(Message msg) {Log.i("Launcher-","mHandler msg.what = " + msg.what);if (msg.what == ADVANCE_MSG) {int i = 0;for (View key : mWidgetsToAdvance.keySet()) {final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);final int delay = mAdvanceStagger * i;if (v instanceof Advanceable) {mHandler.postDelayed(new Runnable() {public void run() {((Advanceable) v).advance();}}, delay);}i++;}sendAdvanceMessage(mAdvanceInterval);}//ADD BY Bruce Yang FOR SHOW UNREAD MMSelse if (msg.what == UPDATE_MMS_ICON) {setMmsOrPhoneNum(MMS_ICON_NAME, getMissMmsCount());} else if (msg.what == UPDATE_CALL_ICON) {setMmsOrPhoneNum(PHONE_ICON_NAME, getMissCallCount());}return true;}
});
  • 获取数据库中未读数目
 private int getMissMmsCount() {Log.i("Launcher-","getMissMmsCount");int missSmsCount = 0;Cursor cursorSMS = null;Cursor cursorMMS = null;try {cursorSMS = getContentResolver().query(Uri.parse("content://sms"), null, "(read=0 and type=1)",null, null);cursorMMS = getContentResolver().query(Uri.parse("content://mms"), null, "(read=0)", null,null);} catch (SQLiteException e) {return missSmsCount;}if (cursorSMS != null) {missSmsCount = cursorSMS.getCount();cursorSMS.close();}if (cursorMMS != null) {missSmsCount = missSmsCount + cursorMMS.getCount();cursorMMS.close();}Log.i("Launcher-","getMissMmsCount  missSmsCount = " + missSmsCount);return missSmsCount;
}private int getMissCallCount() {Log.i("Launcher-","getMissCallCount");int missCallCount = 0;Uri missingCallUri = Calls.CONTENT_URI;String where = Calls.TYPE + "='" + Calls.MISSED_TYPE + "'"+ " AND new=1";Cursor cursorCall = null;try {cursorCall = getContentResolver().query(missingCallUri,null, where, null, null);} catch (SQLiteException e) {return missCallCount;}if (cursorCall != null) {missCallCount = cursorCall.getCount();cursorCall.close();}Log.i("Launcher-","getMissCallCount  missCallCount = " + missCallCount);return missCallCount;
}
  • 设置 ICON 未读数
/**** @param flag 更新电话或短信 ICON* @param missCount 未读数
*/
private void setMmsOrPhoneNum(final String flag, final int missCount) {Log.i("Launcher-","flag = "+flag +" missCount = "+missCount);if(mWorkspace == null) return;ArrayList<CellLayout> cellLayouts = mWorkspace.getWorkspaceAndHotseatCellLayouts();for (final CellLayout layoutParent: cellLayouts) {final ViewGroup shortcutAndWidgetContainer = layoutParent.getShortcutsAndWidgets();mWorkspace.post(new Runnable() {public void run() {int childCount = shortcutAndWidgetContainer.getChildCount();for (int j = 0; j <childCount; j++) {View view = shortcutAndWidgetContainer.getChildAt(j);Object tag = view.getTag();if (tag instanceof ShortcutInfo) {final ShortcutInfo info = (ShortcutInfo) tag;final Intent intent = info.intent;if (intent != null) {final ComponentName name = intent.getComponent();if (name != null && name.getClassName().equals(flag)) {BubbleTextView bv = (BubbleTextView) view;Bitmap defaultIconBitmap = Bitmap.createBitmap(info.getIcon(mIconCache));Bitmap bitmap = Utilities.createIconBitmap(defaultIconBitmap, missCount);bv.setCompoundDrawablesWithIntrinsicBounds(null,new FastBitmapDrawable(bitmap),null, null);}}}}}});}
}
  • 第一次启动 Launcher 就能获取未读数目,在 finishBindingItems() 添加逻辑
//ADD BY Bruce Yang
int missCall = getMissCallCount();
int missMms = getMissMmsCount();
if(missCall != 0) {setMmsOrPhoneNum(PHONE_ICON_NAME, missCall);
}
if(missMms != 0) {setMmsOrPhoneNum(MMS_ICON_NAME, missMms);
}
  • 在 onDestroy() 中反注册 ContentObserver
getContentResolver().unregisterContentObserver(smsContentObserver);
getContentResolver().unregisterContentObserver(callContentObserver);

2. Utilities.java

新增构造方法,用于重新绘制带数字的应用图标。

//add by Bruce Yang for ...
static Bitmap createIconBitmap(Bitmap b, int count) {Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888,true);Log.i("Launcher-","b.isMutable() = "+b.isMutable()); // 如果为 false 就会抛出 java.lang.IllegalStateException 异常, http://bbs.csdn.net/topics/370021698if (count == 0) return b;int textureWidth = bitmap.getWidth();final Canvas canvas = sCanvas;Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);canvas.setBitmap(bitmap);paint.setColor(Color.RED);canvas.drawCircle(textureWidth - 17-6, 16+6, 16+6, paint);paint.setColor(Color.WHITE);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(2);canvas.drawCircle(textureWidth - 17-6, 16+6, 16+6, paint);Paint countPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);countPaint.setColor(Color.WHITE);countPaint.setTextSize(26f);countPaint.setTypeface(Typeface.DEFAULT_BOLD);float x = textureWidth - 24-4;if (count > 9) x -= 4+6;if (count > 99) {countPaint.setTextSize(22f);String text = String.valueOf(99) + "+";canvas.drawText(text, x-2, 25+5, countPaint);} else {String text = String.valueOf(count);canvas.drawText(text,x, 25+5, countPaint);}return bitmap;
}

3. AndroidManifest.xml

添加如下两个权限,由于 Android 6.0 以上需要动态权限申请,这里为了直接获取权限,可以将 targetSdkVersion 改成 21(原来是 23)。

<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />

4. 修改对比

修改前:

修改后:

参考文章:

http://blog.csdn.net/chenxiong668/article/details/12851357
http://blog.csdn.net/kerancsdn/article/details/26705767

Android Launcher 界面添加未接来电 / 未读短信条数显示相关推荐

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

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

  2. 获取未接来电及新短信的小栗子(主要使用ContentObserver类)

    1.ContentObserver简单介绍:     ContentObserver--内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器( ...

  3. Android有未接来电后处理(判断未接来电)

    在Android的手机状态中没有未接来电的监听器,所以如果想当手机有未接来电后进行处理,这时候就需要自己对手机的状态判断是未接来电后再进行处理. 实现思路 : 1. 继承PhoneStateListe ...

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

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

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

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

  6. Android MTK N 平台上如何在桌面上添加未接来电和未接信息数字角标

    本篇博客我们来实现在桌面上添加未接来电和未接信息数字角标的功能. 想要实现这个功能,我们需要监听到未接来电/未接短信的变化,同时获取到未接来电/未接短信的数量,当监听到变化时对对应的图标进行重绘,在图 ...

  7. Android获取通话记录的未接来电、自定义通知栏事件处理

    此文非教程,作常用工具类记录,因此主要是代码--- --前言 公司项目有这么一个需求,获取用户的通话记录,如果存在24小时内的未接来电则发送状态栏通知,通知上除了可以直接回拨还可以及引导用户打开app ...

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

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

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

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

最新文章

  1. AI芯片体系结构目标图形处理
  2. 电脑中所有exe文件无法运行解决方案
  3. three.js 背景图片
  4. oracle 控制文件在哪里设置_从Oracle到PostgreSQL:最全控制文件
  5. 初步了解Linux strace 命令和跟踪进程产生的系统调用
  6. vs 构建linux 项目,使用Linux上的Mono构建VS 2017 MSBuild csproj项目
  7. js 验证各种格式类型的正则表达式
  8. 超实用的mysql分库分表策略,轻松解决亿级数据问题
  9. android电源管理白名单,刷BIOS工具分享(白名单,高级菜单,电源管理)
  10. HDAO去中心化社区自治平台,助力明星项目启航
  11. SQL Server超详细使用教程——从安装到编写SQL语句
  12. 强化学习笔记1:Multi-armed Bandits
  13. [QUANTAXIS量化分析]羊驼策略1
  14. IP解析成地址 确定省市
  15. 【面试题】:工人分金条问题
  16. jenkins中使用脚本来节省资源空间和使用shell提取文件名或目录名的方法
  17. Android学习:访问网络
  18. 数学分析 导数与微分(第5章)
  19. Linux安装Phantomjs
  20. VScode无法启动--- 感谢百度,感谢好人,感谢CCTV

热门文章

  1. 【机器学习】回归树生成过程及举例理解
  2. python+adb实现截屏/录屏功能
  3. 【8-13】手势传感器PAJ7620U2测试 实现手势控制无人机
  4. Illustrator CS5初学者必读(3)——渐变填充
  5. 树莓派4B摄像头的详细使用教程(拍照+录像+监控)
  6. Typora软件介绍
  7. 解18位身份证正则表达式
  8. hihocoder编程练习赛73 A 地铁站
  9. 苹果文件夹建立服务器显示没网,Mac系统怎么设置隐藏和显示文件或文件夹?_苹果...
  10. Java判断回文序列