您的位置:首页 > 移动开发 > Android开发

如何在android4.4上添加未读信息,未接来电或日历新事件提醒等功能

2014-04-03 10:37 399 查看
如何在android4.4上添加未读信息,未接来电或日历新事件提醒等功能,android4.2上

很多商家都已实现,其实将其移植过来就可以了,不过4.4有许多类变化了,要稍作修

改,下面将列出要修改哪些类?添加些什么方法?

详细修改如下:

1.首先准备各种大小的ic_newevents_numberindication.9.png图片,这个自己去找吧

,如果你是搞开发的,在以前的项目中都可以找到的。

2.定义个未读信息支持的app事件xml,我这个支持短信,日历,电话,邮件:

b/packages/apps/Launcher3/res/xml/unread_support_shortcuts.xml

内容如下:

+<?xml version="1.0" encoding="UTF-8"?>

+<unreadshortcuts xmlns:launcher="http://schemas.android.com/apk/res-

auto/com.android.launcher3">

+

+ <shortcut

+ launcher:unreadPackageName="com.android.dialer"

+ launcher:unreadClassName="com.android.dialer.DialtactsActivity"

+ launcher:unreadType="0"

+ launcher:unreadKey="com_android_contacts_unread"

+ />

+ <shortcut

+ launcher:unreadPackageName="com.android.mms"

+ launcher:unreadClassName="com.android.mms.ui.BootActivity"

+ launcher:unreadType="0"

+ launcher:unreadKey="com_android_mms_unread"

+ />

+ <shortcut

+ launcher:unreadPackageName="com.android.email"

+ launcher:unreadClassName="com.android.email.activity.Welcome"

+ launcher:unreadType="0"

+ launcher:unreadKey="com_android_email_unread"

+ />

+ <shortcut

+ launcher:unreadPackageName="com.android.calendar"

+ launcher:unreadClassName="com.android.calendar.AllInOneActivity"

+ launcher:unreadType="0"

+ launcher:unreadKey="com_android_calendar_unread"

+ />

+ <shortcut

+ launcher:unreadPackageName="com.orangelabs.rcs"

+

launcher:unreadClassName="com.mediatek.rcse.activities.ChatMainActivity"

+ launcher:unreadType="0"

+ launcher:unreadKey="com_android_rcse_unread"

+ />

+ <shortcut

+ launcher:unreadPackageName="com.android.cellbroadcastreceiver"

+

launcher:unreadClassName="com.android.cellbroadcastreceiver.CellBroadcastLis

tActivity"

+ launcher:unreadType="0"

+ launcher:unreadKey="com_android_calendar_unread"

+ />

+ <shortcut

+ launcher:unreadPackageName="com.mediatek.cellbroadcastreceiver"

+

launcher:unreadClassName="com.mediatek.cellbroadcastreceiver.CellBroadcastLi

stActivity"

+ launcher:unreadType="0"

+ launcher:unreadKey="com_mediatek_cellbroadcastreceiver_unread"

+ />

+</unreadshortcuts>

3.添加几种需要用到而之前没有的权限:

b/packages/apps/Launcher3/AndroidManifest.xml

<original-package android:name="com.android.launcher3" />

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

+ <uses-permission

android:name="android.permission.ADVANCED_WIDGET_API"/>

+ <uses-permission android:name="android.permission.WRITE_SETTINGS"/>

+ <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>

+ <uses-permission android:name="android.permission.DELETE_PACKAGES"/>

4.定义要用的字符串:b/packages/apps/Launcher3/res/values/attrs.xml

+ <!-- XML attributes used by unread_support_shortcuts.xml -->

+ <declare-styleable name="UnreadShortcut">

+ <attr name="unreadPackageName" format="string" />

+ <attr name="unreadClassName" format="string" />

+ <attr name="unreadKey" format="string" />

+ <attr name="unreadType" format="integer" />

+ </declare-styleable>

5.定义显示的数字大小尺寸,这个可以自己修改到满意,这个是四行五列排列的

1080*1920屏幕大小的尺寸。

b/packages/apps/Launcher3/res/values/dimens.xml

+ <!-- Add for unread events feature. -->

+ <dimen name="unread_minWidth">20dp</dimen>

+ <dimen name="hotseat_unread_margin_top">16dp</dimen>

+ <dimen name="hotseat_unread_margin_right">8dp</dimen>

+ <dimen name="folder_unread_margin_top">16dp</dimen>

+ <dimen name="folder_unread_margin_right">14dp</dimen>

+ <dimen name="workspace_unread_margin_top">16dp</dimen>

+ <dimen name="workspace_unread_margin_right">16dp</dimen>

+ <dimen name="app_list_unread_margin_top">20dp</dimen>

+ <dimen name="app_list_unread_margin_right">16dp</dimen>

+ <dimen name="unread_text_margin">8dp</dimen>

+ <dimen name="unread_text_number_size">14sp</dimen>

+ <dimen name="unread_text_plus_size">10sp</dimen>

6.接下来就是写一个类了,这里命名为UnreadLoader.java:

b/packages/apps/Launcher3/src/com/android/launcher3/UnreadLoader.java

package com.android.launcher3;

import android.content.BroadcastReceiver;

import android.content.ComponentName;

import android.content.ContentResolver;

import android.content.Context;

import android.content.Intent;

import android.content.res.Resources;

import android.content.res.TypedArray;

import android.content.res.XmlResourceParser;

import android.graphics.Canvas;

import android.graphics.drawable.NinePatchDrawable;

import android.graphics.Paint;

import android.graphics.Rect;

import android.graphics.Typeface;

import android.os.AsyncTask;

import android.text.Spannable;

import android.text.SpannableStringBuilder;

import android.text.style.AbsoluteSizeSpan;

import android.text.style.SuperscriptSpan;

import android.util.AttributeSet;

import android.util.Xml;

import android.view.View;

import com.android.internal.util.XmlUtils;

import com.android.launcher3.R;

import com.mediatek.launcher3.ext.LauncherLog;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

import java.lang.ref.WeakReference;

import java.util.ArrayList;

class UnreadSupportShortcut {

public UnreadSupportShortcut(String pkgName, String clsName, String

keyString, int type) {

mComponent = new ComponentName(pkgName, clsName);

mKey = keyString;

mShortcutType = type;

mUnreadNum = 0;

}

ComponentName mComponent;

String mKey;

int mShortcutType;

int mUnreadNum;

@Override

public String toString() {

return "{UnreadSupportShortcut[" + mComponent + "], key = " + mKey +

",type = "

+ mShortcutType + ",unreadNum = " + mUnreadNum + "}";

}

}

/**

* M: This class is a util class, implemented to do the following two

things,:

*

* 1.Read config xml to get the shortcuts which support displaying unread

number,

* then get the initial value of the unread number of each component and

update

* shortcuts and folders through callbacks implemented in Launcher.

*

* 2. Receive unread broadcast sent by application, update shortcuts and

folders in

* workspace, hot seat and update application icons in app customize paged

view.

*/

public class UnreadLoader extends BroadcastReceiver {

private static final String TAG = "UnreadLoader";

private static final String TAG_UNREADSHORTCUTS = "unreadshortcuts";

private static final ArrayList<UnreadSupportShortcut>

UNREAD_SUPPORT_SHORTCUTS = new ArrayList<UnreadSupportShortcut>();

private static int sUnreadSupportShortcutsNum = 0;

private static final Object LOG_LOCK = new Object();

private Context mContext;

private WeakReference<UnreadCallbacks> mCallbacks;

public UnreadLoader(Context context) {

mContext = context;

}

@Override

public void onReceive(final Context context, final Intent intent) {

final String action = intent.getAction();

if (Intent.XXX_ACTION_UNREAD_CHANGED.equals(action)) {

final ComponentName componentName = (ComponentName) intent

.getExtra(Intent.XXX_EXTRA_UNREAD_COMPONENT);

final int unreadNum = intent.getIntExtra

(Intent.XXX_EXTRA_UNREAD_NUMBER, -1);

if (LauncherLog.DEBUG) {

LauncherLog.d(TAG, "Receive unread broadcast: componentName

= " + componentName

+ ", unreadNum = " + unreadNum + ", mCallbacks = " +

mCallbacks

+ getUnreadSupportShortcutInfo());

}

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);

}

}

}

}

}

}

/**

* Set this as the current Launcher activity object for the loader.

*/

public void initialize(UnreadCallbacks callbacks) {

mCallbacks = new WeakReference<UnreadCallbacks>(callbacks);

if (LauncherLog.DEBUG_UNREAD) {

LauncherLog.d(TAG, "initialize: callbacks = " + callbacks + ",

mCallbacks = " + mCallbacks);

}

}

/**

* Load and initialize unread shortcuts.

*

* @param context

*/

void loadAndInitUnreadShortcuts() {

new AsyncTask<Void, Void, Void>() {

@Override

protected Void doInBackground(Void... unused) {

loadUnreadSupportShortcuts();

initUnreadNumberFromSystem();

return null;

}

@Override

protected void onPostExecute(final Void result) {

if (mCallbacks != null) {

UnreadCallbacks callbacks = mCallbacks.get();

if (callbacks != null) {

callbacks.bindUnreadInfoIfNeeded();

}

}

}

}.execute();

}

/**

* Initialize unread number by querying system settings provider.

*

* @param context

*/

private void initUnreadNumberFromSystem() {

final ContentResolver cr = mContext.getContentResolver();

final int shortcutsNum = sUnreadSupportShortcutsNum;

UnreadSupportShortcut shortcut = null;

for (int i = 0; i < shortcutsNum; i++) {

shortcut = UNREAD_SUPPORT_SHORTCUTS.get(i);

try {

shortcut.mUnreadNum =

android.provider.Settings.System.getInt(cr, shortcut.mKey);

if (LauncherLog.DEBUG_UNREAD) {

LauncherLog.d(TAG, "initUnreadNumberFromSystem: key = "

+ shortcut.mKey

+ ", unreadNum = " + shortcut.mUnreadNum);

}

} catch (android.provider.Settings.SettingNotFoundException e) {

LauncherLog.e(TAG, "initUnreadNumberFromSystem

SettingNotFoundException key = "

+ shortcut.mKey + ", e = " + e.getMessage());

}

}

if (LauncherLog.DEBUG_UNREAD) {

LauncherLog.d(TAG, "initUnreadNumberFromSystem end:" +

getUnreadSupportShortcutInfo());

}

}

private void loadUnreadSupportShortcuts() {

long start = System.currentTimeMillis();

if (LauncherLog.DEBUG_PERFORMANCE) {

LauncherLog.d(TAG, "loadUnreadSupportShortcuts begin: start = "

+ start);

}

// Clear all previous parsed unread shortcuts.

UNREAD_SUPPORT_SHORTCUTS.clear();

try {

XmlResourceParser parser = mContext.getResources().getXml(

R.xml.unread_support_shortcuts);

AttributeSet attrs = Xml.asAttributeSet(parser);

XmlUtils.beginDocument(parser, TAG_UNREADSHORTCUTS);

final int depth = parser.getDepth();

int type = -1;

while (((type = parser.next()) != XmlPullParser.END_TAG ||

parser.getDepth() > depth)

&& type != XmlPullParser.END_DOCUMENT) {

if (type != XmlPullParser.START_TAG) {

continue;

}

TypedArray a = mContext.obtainStyledAttributes(attrs,

R.styleable.UnreadShortcut);

synchronized (LOG_LOCK) {

UNREAD_SUPPORT_SHORTCUTS.add(new UnreadSupportShortcut(a

.getString

(R.styleable.UnreadShortcut_unreadPackageName), a

.getString

(R.styleable.UnreadShortcut_unreadClassName), a

.getString

(R.styleable.UnreadShortcut_unreadKey), a.getInt(

R.styleable.UnreadShortcut_unreadType, 0)));

}

a.recycle();

}

} catch (XmlPullParserException e) {

LauncherLog.w(TAG, "Got XmlPullParserException while parsing

unread shortcuts.", e);

} catch (IOException e) {

LauncherLog.w(TAG, "Got IOException while parsing unread

shortcuts.", e);

}

sUnreadSupportShortcutsNum = UNREAD_SUPPORT_SHORTCUTS.size();

if (LauncherLog.DEBUG_PERFORMANCE) {

LauncherLog.d(TAG, "loadUnreadSupportShortcuts end: time used =

"

+ (System.currentTimeMillis() - start) +

",sUnreadSupportShortcutsNum = "

+ sUnreadSupportShortcutsNum +

getUnreadSupportShortcutInfo());

}

}

/**

* Get unread support shortcut information, since the information are

stored

* in an array list, we may query it and modify it at the same time, a

lock

* is needed.

*

* @return

*/

private static String getUnreadSupportShortcutInfo() {

String info = " Unread support shortcuts are ";

synchronized (LOG_LOCK) {

info += UNREAD_SUPPORT_SHORTCUTS.toString();

}

return info;

}

/**

* Whether the given component support unread feature.

*

* @param component

* @return

*/

static int supportUnreadFeature(ComponentName component) {

if (LauncherLog.DEBUG_UNREAD) {

LauncherLog.d(TAG, "supportUnreadFeature: component = " +

component);

}

if (component == null) {

return -1;

}

final int size = UNREAD_SUPPORT_SHORTCUTS.size();

for (int i = 0, sz = size; i < sz; i++) {

if (UNREAD_SUPPORT_SHORTCUTS.get(i).mComponent.equals

(component)) {

return i;

}

}

return -1;

}

/**

* Set the unread number of the item in the list with the given unread

number.

*

* @param index

* @param unreadNum

* @return

*/

static synchronized boolean setUnreadNumberAt(int index, int unreadNum)

{

if (index >= 0 || index < sUnreadSupportShortcutsNum) {

if (LauncherLog.DEBUG_UNREAD) {

LauncherLog.d(TAG, "setUnreadNumberAt: index = " + index +

",unreadNum = " + unreadNum

+ getUnreadSupportShortcutInfo());

}

if (UNREAD_SUPPORT_SHORTCUTS.get(index).mUnreadNum != unreadNum)

{

UNREAD_SUPPORT_SHORTCUTS.get(index).mUnreadNum = unreadNum;

return true;

}

}

return false;

}

/**

* Get unread number of application at the given position in the

supported

* shortcut list.

*

* @param index

* @return

*/

static synchronized int getUnreadNumberAt(int index) {

if (index < 0 || index >= sUnreadSupportShortcutsNum) {

return 0;

}

if (LauncherLog.DEBUG_UNREAD) {

LauncherLog.d(TAG, "getUnreadNumberAt: index = " + index

+ getUnreadSupportShortcutInfo());

}

return UNREAD_SUPPORT_SHORTCUTS.get(index).mUnreadNum;

}

/**

* Get unread number for the given component.

*

* @param component

* @return

*/

static int getUnreadNumberOfComponent(ComponentName component) {

final int index = supportUnreadFeature(component);

return getUnreadNumberAt(index);

}

/**

* Draw unread number for the given icon.

*

* @param canvas

* @param icon

* @return

*/

static void drawUnreadEventIfNeed(Canvas canvas, View icon) {

ItemInfo info = (ItemInfo)icon.getTag();

if (info != null && info.unreadNum > 0) {

Resources res = icon.getContext().getResources();

/// M: Meature sufficent width for unread text and background

image

Paint unreadTextNumberPaint = new Paint();

unreadTextNumberPaint.setTextSize(res.getDimension

(R.dimen.unread_text_number_size));

unreadTextNumberPaint.setTypeface(Typeface.DEFAULT_BOLD);

unreadTextNumberPaint.setColor(0xffffffff);

unreadTextNumberPaint.setTextAlign(Paint.Align.CENTER);

Paint unreadTextPlusPaint = new Paint(unreadTextNumberPaint);

unreadTextPlusPaint.setTextSize(res.getDimension

(R.dimen.unread_text_plus_size));

String unreadTextNumber;

String unreadTextPlus = "+";

Rect unreadTextNumberBounds = new Rect(0, 0, 0, 0);

Rect unreadTextPlusBounds = new Rect(0, 0, 0, 0);

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();

/// M: Draw unread background image.

NinePatchDrawable unreadBgNinePatchDrawable =

(NinePatchDrawable) res.getDrawable

(R.drawable.ic_newevents_numberindication);

int unreadBgWidth = unreadBgNinePatchDrawable.getIntrinsicWidth

();

int unreadBgHeight =

unreadBgNinePatchDrawable.getIntrinsicHeight();

int unreadMinWidth = (int) res.getDimension

(R.dimen.unread_minWidth);

if (unreadBgWidth < unreadMinWidth) {

unreadBgWidth = unreadMinWidth;

}

int unreadTextMargin = (int) res.getDimension

(R.dimen.unread_text_margin);

if (unreadBgWidth < textWidth + unreadTextMargin) {

unreadBgWidth = textWidth + unreadTextMargin;

}

if (unreadBgHeight < textHeight) {

unreadBgHeight = textHeight;

}

Rect unreadBgBounds = new Rect(0, 0, unreadBgWidth,

unreadBgHeight);

unreadBgNinePatchDrawable.setBounds(unreadBgBounds);

int unreadMarginTop = 0;

int unreadMarginRight = 0;

if (info instanceof ShortcutInfo) {

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) {

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 {

canvas.drawText(unreadTextNumber,

unreadBgWidth / 2,

(unreadBgHeight + textHeight) / 2,

unreadTextNumberPaint);

}

canvas.restore();

}

}

public interface UnreadCallbacks {

/**

* Bind shortcuts and application icons with the given component,

and

* update folders unread which contains the given component.

*

* @param component

* @param unreadNum

*/

void bindComponentUnreadChanged(ComponentName component, int

unreadNum);

/**

* Bind unread shortcut information if needed, this call back is

used to

* update shortcuts and folders when launcher first created.

*/

void bindUnreadInfoIfNeeded();

}

}

7.为桌面应用程序添加未读事件,4.2上用到的是ApplicationInfo和

PageViewCellLayout,不过这里要改为AppInfo和AppsCustomizeCellLayout: 在

AppsCustomizePagedView.java中增加

添加方法:

+ /**

+ * M: Update unread number of the given component in app customize

paged view

+ * with the given value, first find the icon, and then update the

number.

+ * NOTES: since maybe not all applications are added in the customize

paged

+ * view, we should update the apps info at the same time.

+ *

+ * @param component

+ * @param unreadNum

+ */

+ public void updateAppsUnreadChanged(ComponentName component, int

unreadNum) {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateAppsUnreadChanged: component = " +

component

+ + ",unreadNum = " + unreadNum + ",mNumAppsPages = " +

mNumAppsPages);

+ }

+ updateUnreadNumInAppInfo(component, unreadNum);

+ for (int i = 0; i < mNumAppsPages; i++) {

+ AppsCustomizeCellLayout cl = (AppsCustomizeCellLayout)

getPageAt(i);

+ if (cl == null) {

+ return;

+ }

+ final int count = cl.getPageChildCount();

+ View appIcon = null;

+ AppInfo appInfo = null;

+ for (int j = 0; j < count; j++) {

+ appIcon = cl.getChildOnPageAt(j);

+ appInfo = (AppInfo) appIcon.getTag();

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateAppsUnreadChanged: component

= " + component

+ + ", appInfo = " + appInfo.componentName + ",

appIcon = " + appIcon);

+ }

+ if (appInfo != null && appInfo.componentName.equals

(component)) {

+ appInfo.unreadNum = unreadNum;

+ appIcon.invalidate();

+ }

+ }

+ }

+ }

+ /**

+ * M: Update unread number of all application info with data in

UnreadLoader.

+ */

+ public void updateAppsUnread() {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateAppsUnreadChanged: mNumAppsPages = "

+ mNumAppsPages);

+ }

+

+ updateUnreadNumInAppInfo(mApps);

+ // Update apps which already shown in the customized pane.

+ for (int i = 0; i < mNumAppsPages; i++) {

+ AppsCustomizeCellLayout cl = (AppsCustomizeCellLayout)

getPageAt(i);

+ if (cl == null) {

+ return;

+ }

+ final int count = cl.getPageChildCount();

+ View appIcon = null;

+ AppInfo appInfo = null;

+ for (int j = 0; j < count; j++) {

+ appIcon = cl.getChildOnPageAt(j);

+ appInfo = (AppInfo) appIcon.getTag();

+ appInfo.unreadNum =

UnreadLoader.getUnreadNumberOfComponent(appInfo.componentName);

+ appIcon.invalidate();

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateAppsUnreadChanged: i = " + i

+ ", appInfo = "

+ + appInfo.componentName + ", unreadNum = " +

appInfo.unreadNum);

+ }

+ }

+ }

+ }

+ /**

+ * M: Update the unread number of the app info with given component.

+ *

+ * @param component

+ * @param unreadNum

+ */

+ private void updateUnreadNumInAppInfo(ComponentName component, int

unreadNum) {

+ final int size = mApps.size();

+ AppInfo appInfo = null;

+ for (int i = 0; i < size; i++) {

+ appInfo = mApps.get(i);

+ if (appInfo.intent.getComponent().equals(component)) {

+ appInfo.unreadNum = unreadNum;

+ }

+ }

+ }

+ /**

+ * M: Update unread number of all application info with data in

UnreadLoader.

+ *

+ * @param apps

+ */

+ public static void updateUnreadNumInAppInfo(final ArrayList<AppInfo>

apps) {

+ final int size = apps.size();

+ AppInfo appInfo = null;

+ for (int i = 0; i < size; i++) {

+ appInfo = apps.get(i);

+ appInfo.unreadNum = UnreadLoader.getUnreadNumberOfComponent

(appInfo.componentName);

+ }

+ }

8.为文件夹添加未读事件

Folder.java类

+ /**

+ * M: Update unread number of the content shortcut.

+ */

+ public void updateContentUnreadNum() {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "Folder updateContentUnreadNum: mInfo = " +

mInfo);

+ }

+ final int countX = mContent.getCountX();

+ final int countY = mContent.getCountY();

+ for (int j = 0; j < countY; j++) {

+ for (int i = 0; i < countX; i++) {

+ BubbleTextView shortcut = (BubbleTextView)

mContent.getChildAt(i, j);

+ if (shortcut != null) {

+ shortcut.invalidate();

+ }

+ }

+ }

+ }

9.定义未读变量:ItemInfo.java类中

+ /**

+ * M: The unread num of the item.

+ */

+ int unreadNum = 0;

然后在构造函数中给它初始化:

+ unreadNum = info.unreadNum;

在toString()方法中增加 该变量+ " unreadNum= " + unreadNum + ")";

其次在ShortcutInfo.java类的toString方法中也增加该变量。

10.在Launcher.java类中调用写的方法:

首先在实现类中增加implements UnreadLoader.UnreadCallbacks 。。。

private UnreadLoader mUnreadLoader;//定义UnreadLoader对象

在onCreate方法中添加

+ /// M: added for unread feature, load and bind unread info.

+ if (FeatureOption.XXX_LAUNCHER_UNREAD_SUPPORT) {//不同平台这个字符

串可能不一样,XXX是平台名,这个字符串之后也一样的换成自己的就好了

+ mUnreadLoader = app.getUnreadLoader();

+ mUnreadLoader.loadAndInitUnreadShortcuts();

+ }

增加几个方法:

+/**

+ * M: Bind component unread information in workspace and all apps list.

+ *

+ * @param component the component name of the app.

+ * @param unreadNum the number of the unread message.

+ */

+ public void bindComponentUnreadChanged(final ComponentName component,

final int unreadNum) {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "bindComponentUnreadChanged: component = " +

component

+ + ", unreadNum = " + unreadNum + ", this = " + this);

+ }

+ // Post to message queue to avoid possible ANR.

+ mHandler.post(new Runnable() {

+ public void run() {

+ final long start = System.currentTimeMillis();

+ if (LauncherLog.DEBUG_PERFORMANCE) {

+ LauncherLog.d(TAG, "bindComponentUnreadChanged begin:

component = " + component

+ + ", unreadNum = " + unreadNum + ", start = " +

start);

+ }

+ if (mWorkspace != null) {

+ mWorkspace.updateComponentUnreadChanged(component,

unreadNum);

+ }

+

+ if (mAppsCustomizeContent != null) {

+ mAppsCustomizeContent.updateAppsUnreadChanged

(component, unreadNum);

+ }

+ if (LauncherLog.DEBUG_PERFORMANCE) {

+ LauncherLog.d(TAG, "bindComponentUnreadChanged end:

current time = "

+ + System.currentTimeMillis() + ", time used = "

+ + (System.currentTimeMillis() - start));

+ }

+ }

+ });

+ }

+ /**

+ * M: Bind shortcuts unread number if binding process has finished.

+ */

+ public void bindUnreadInfoIfNeeded() {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "bindUnreadInfoIfNeeded:

mBindingWorkspaceFinished = "

+ + mBindingWorkspaceFinished + ", thread = " +

Thread.currentThread());

+ }

+ if (mBindingWorkspaceFinished) {

+ bindWorkspaceUnreadInfo();

+ }

+

+ if (mBindingAppsFinished) {

+ bindAppsUnreadInfo();

+ }

+ mUnreadLoadCompleted = true;

+ }

+ /**

+ * M: Bind unread number to shortcuts with data in UnreadLoader.

+ */

+ private void bindWorkspaceUnreadInfo() {

+ mHandler.post(new Runnable() {

+ public void run() {

+ final long start = System.currentTimeMillis();

+ if (LauncherLog.DEBUG_PERFORMANCE) {

+ LauncherLog.d(TAG, "bindWorkspaceUnreadInfo begin:

start = " + start);

+ }

+ if (mWorkspace != null) {

+ mWorkspace.updateShortcutsAndFoldersUnread();

+ }

+ if (LauncherLog.DEBUG_PERFORMANCE) {

+ LauncherLog.d(TAG, "bindWorkspaceUnreadInfo end:

current time = "

+ + System.currentTimeMillis() + ",time used = "

+ + (System.currentTimeMillis() - start));

+ }

+ }

+ });

+ }

+ /**

+ * M: Bind unread number to shortcuts with data in UnreadLoader.

+ */

+ private void bindAppsUnreadInfo() {

+ mHandler.post(new Runnable() {

+ public void run() {

+ final long start = System.currentTimeMillis();

+ if (LauncherLog.DEBUG_PERFORMANCE) {

+ LauncherLog.d(TAG, "bindAppsUnreadInfo begin: start = "

+ start);

+ }

+ if (mAppsCustomizeContent != null) {

+ mAppsCustomizeContent.updateAppsUnread();

+ }

+ if (LauncherLog.DEBUG_PERFORMANCE) {

+ LauncherLog.d(TAG, "bindAppsUnreadInfo end: current

time = "

+ + System.currentTimeMillis() + ",time used = "

+ + (System.currentTimeMillis() - start));

+ }

+ }

+ });

+ }

+

11.接下来在LauncherAppState.java中添加一些方法,主要是注册广播,4.2上没这个

类,是在LauncherApplication.java中添加,这是4.4上新增的,基本上代替了

LauncherApplication.java

首先导入FeatureOption该类,这个各个平台路径可能不一样,所以自己去找吧

+ /// M: added for unread feature.

+ private UnreadLoader mUnreadLoader; //定义对象

在相应的地方注册广播

+ /// M: register unread broadcast.

+ if (FeatureOption.XXX_LAUNCHER_UNREAD_SUPPORT) {

+ mUnreadLoader = new UnreadLoader(sContext);

+ // Register unread change broadcast.

+ filter = new IntentFilter();

+ filter.addAction(Intent.XXX_ACTION_UNREAD_CHANGED);

+ sContext.registerReceiver(mUnreadLoader, filter);

+ LauncherLog.d(TAG, "register unread broadcast successfully");

+ }

同时在相应的地方注销广播

+ /// M: added for unread feature, unregister unread receiver.

+ if (FeatureOption.XXX_LAUNCHER_UNREAD_SUPPORT) {

+ sContext.unregisterReceiver(mUnreadLoader);

+ }

在setLauncher方法中初始化未读事件

/// M: added for unread feature, initialize unread loader.

if (FeatureOption.XXX_LAUNCHER_UNREAD_SUPPORT) {

mUnreadLoader.initialize(launcher);

}

增加一个方法:

+ /**

+ * M: Get unread loader, added for unread feature.

+ */

+ public UnreadLoader getUnreadLoader() {

+ return mUnreadLoader;

+ }

13.Workspace.java类中增加方法:

+ /**

+ * M: Update unread number of shortcuts and folders in workspace and

hotseat.

+ */

+ public void updateShortcutsAndFoldersUnread() {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateShortcutsAndFolderUnread: this = " +

this);

+ }

+ final ArrayList<ShortcutAndWidgetContainer> childrenLayouts =

getAllShortcutAndWidgetContainers();

+ int childCount = 0;

+ View view = null;

+ Object tag = null;

+ for (ShortcutAndWidgetContainer layout : childrenLayouts) {

+ childCount = layout.getChildCount();

+ for (int j = 0; j < childCount; j++) {

+ view = layout.getChildAt(j);

+ tag = view.getTag();

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateShortcutsAndFoldersUnread:

tag = " + tag + ", j = "

+ + j + ", view = " + view);

+ }

+ if (tag instanceof ShortcutInfo) {

+ final ShortcutInfo info = (ShortcutInfo) tag;

+ final Intent intent = info.intent;

+ final ComponentName componentName =

intent.getComponent();

+ info.unreadNum =

MTKUnreadLoader.getUnreadNumberOfComponent(componentName);

+ ((BubbleTextView) view).invalidate();

+ } else if (tag instanceof FolderInfo) {

+ ((FolderIcon) view).updateFolderUnreadNum();

+ ((FolderIcon) view).invalidate();

+ }

+ }

+ }

+ }

+ /**

+ * M: Update unread number of shortcuts and folders in workspace and

hotseat

+ * with the given component.

+ *

+ * @param component

+ * @param unreadNum

+ */

+ public void updateComponentUnreadChanged(ComponentName component, int

unreadNum) {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateComponentUnreadChanged: component = "

+ component

+ + ", unreadNum = " + unreadNum);

+ }

+ final ArrayList<ShortcutAndWidgetContainer> childrenLayouts =

getAllShortcutAndWidgetContainers();

+ int childCount = 0;

+ View view = null;

+ Object tag = null;

+ for (ShortcutAndWidgetContainer layout : childrenLayouts) {

+ childCount = layout.getChildCount();

+ for (int j = 0; j < childCount; j++) {

+ view = layout.getChildAt(j);

+ tag = view.getTag();

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateComponentUnreadChanged:

component = " + component

+ + ",tag = " + tag + ",j = " + j + ",view = " +

view);

+ }

+ if (tag instanceof ShortcutInfo) {

+ final ShortcutInfo info = (ShortcutInfo) tag;

+ final Intent intent = info.intent;

+ final ComponentName componentName =

intent.getComponent();

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateComponentUnreadChanged 2:

find component = "

+ + component + ",intent = " + intent +

",componentName = " + componentName);

+ }

+ if (componentName != null && componentName.equals

(component)) {

+ LauncherLog.d(TAG, "updateComponentUnreadChanged 1:

find component = "

+ + component + ",tag = " + tag + ",j = " + j

+ ",cellX = "

+ + info.cellX + ",cellY = " + info.cellY);

+ info.unreadNum = unreadNum;

+ ((BubbleTextView) view).invalidate();

+ }

+ } else if (tag instanceof FolderInfo) {

+ ((FolderIcon) view).updateFolderUnreadNum(component,

unreadNum);

+ ((FolderIcon) view).invalidate();

+ }

+ }

+ }

+ /// M: Update shortcut within folder if open folder exists.

+ Folder openFolder = getOpenFolder();

+ if (openFolder != null) {

+ openFolder.updateContentUnreadNum();

+ }

+ }

14.接下来就简单了,在相应的地方去画要显示的未读数字就好了

1)首先是PagedViewIcon.java中,这个画的是APP右上角的。

先导包

+// M: Add for unread event feature.

+import android.graphics.Canvas;

+import android.graphics.drawable.Drawable;

+import android.graphics.drawable.NinePatchDrawable;

在其Draw()方法中最后调用:(记得加在最后哦,不让你画的东东被app图标遮住了)

+ /// M: For feature unread draw.

+ UnreadLoader.drawUnreadEventIfNeed(canvas, this);

2)其次在BubbleTextView.java类中draw方法中的

if (getCurrentTextColor() == getResources().getColor

(android.R.color.transparent))改条件中增加:

/// M: Draw unread event number.

UnreadLoader.drawUnreadEventIfNeed(canvas, this);

在draw方法最后也增加

/// M: Draw unread event number.

UnreadLoader.drawUnreadEventIfNeed(canvas, this);

3)然后在FolderIcon.java中也要画:

在dispatchDraw方法的最后:

+ /// M: Draw unread event number.

+ UnreadLoader.drawUnreadEventIfNeed(canvas, this);

在onAdd(ShortcutInfo item)方法中

/// M: added for unread feature, when add a item to a folder, we need to

update

/// the unread num of the folder.

final ComponentName componentName = item.intent.getComponent();

updateFolderUnreadNum(componentName, item.unreadNum);

在onRemove(ShortcutInfo item)方法中添加

/// M: added for Unread feature, when remove a item from a folder, we need

to update

/// the unread num of the folder

final ComponentName componentName = item.intent.getComponent();

updateFolderUnreadNum(componentName, item.unreadNum);

不过还得写两个方法:

+ /**

+ * M: Update the unread message number of the shortcut with the given

value.

+ *

+ * @param unreadNum the number of the unread message.

+ */

+ public void setFolderUnreadNum(int unreadNum) {

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "setFolderUnreadNum: unreadNum = " +

unreadNum + ", mInfo = " + mInfo

+ + ", this = " + this);

+ }

+

+ if (unreadNum <= 0) {

+ mInfo.unreadNum = 0;

+ } else {

+ mInfo.unreadNum = unreadNum;

+ }

+ }

+ /**

+ * M: Update unread number of the folder, the number is the total

unread number

+ * of all shortcuts in folder, duplicate shortcut will be only count

once.

+ */

+ public void updateFolderUnreadNum() {

+ final ArrayList<ShortcutInfo> contents = mInfo.contents;

+ final int contentsCount = contents.size();

+ int unreadNumTotal = 0;

+ final ArrayList<ComponentName> components = new

ArrayList<ComponentName>();

+ ShortcutInfo shortcutInfo = null;

+ ComponentName componentName = null;

+ int unreadNum = 0;

+ for (int i = 0; i < contentsCount; i++) {

+ shortcutInfo = contents.get(i);

+ componentName = shortcutInfo.intent.getComponent();

+ unreadNum = MTKUnreadLoader.getUnreadNumberOfComponent

(componentName);

+ if (unreadNum > 0) {

+ shortcutInfo.unreadNum = unreadNum;

+ int j = 0;

+ for (j = 0; j < components.size(); j++) {

+ if (componentName != null && componentName.equals

(components.get(j))) {

+ break;

+ }

+ }

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateFolderUnreadNum:

unreadNumTotal = " + unreadNumTotal

+ + ", j = " + j + ", components.size() = " +

components.size());

+ }

+ if (j >= components.size()) {

+ components.add(componentName);

+ unreadNumTotal += unreadNum;

+ }

+ }

+ }

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateFolderUnreadNum 1 end: unreadNumTotal

= " + unreadNumTotal);

+ }

+ setFolderUnreadNum(unreadNumTotal);

+ }

+ /**

+ * M: Update the unread message of the shortcut with the given

information.

+ *

+ * @param unreadNum the number of the unread message.

+ */

+ public void updateFolderUnreadNum(ComponentName component, int

unreadNum) {

+ final ArrayList<ShortcutInfo> contents = mInfo.contents;

+ final int contentsCount = contents.size();

+ int unreadNumTotal = 0;

+ ShortcutInfo appInfo = null;

+ ComponentName name = null;

+ final ArrayList<ComponentName> components = new

ArrayList<ComponentName>();

+ for (int i = 0; i < contentsCount; i++) {

+ appInfo = contents.get(i);

+ name = appInfo.intent.getComponent();

+ if (name != null && name.equals(component)) {

+ appInfo.unreadNum = unreadNum;

+ }

+ if (appInfo.unreadNum > 0) {

+ int j = 0;

+ for (j = 0; j < components.size(); j++) {

+ if (name != null && name.equals(components.get(j))) {

+ break;

+ }

+ }

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateFolderUnreadNum:

unreadNumTotal = " + unreadNumTotal

+ + ", j = " + j + ", components.size() = " +

components.size());

+ }

+ if (j >= components.size()) {

+ components.add(name);

+ unreadNumTotal += appInfo.unreadNum;

+ }

+ }

+ }

+ if (LauncherLog.DEBUG_UNREAD) {

+ LauncherLog.d(TAG, "updateFolderUnreadNum 2 end: unreadNumTotal

= " + unreadNumTotal);

+ }

+ setFolderUnreadNum(unreadNumTotal);

+ }

+

+ /**

+ * M: Reset the value of the variable of sStaticValuesDirty.

+ */

+ public static void resetValuesDirty() {

+ sStaticValuesDirty = true;

+ }

唉终于是添加完了,好多内容啊,自己做的时候没发现,原理添加了这么多东西,难怪

花了我两天时间。接下来编译就好了,希望各位能一次通过,我当初可是出了七十多个

errors呢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐