日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 4.0 Notification

發布時間:2025/4/5 Android 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 4.0 Notification 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通常,在手機有未接電話,收到消息或者掛著退出主界面的QQ,在狀態欄會有一個Notification,那么,這個notification如何產生的?

通常做法:

Intent?intent?=?new?Intent();

????????intent.setClass(this,?Noti.class);

//一般而言,對于需要點擊Notification需要遷移到對應的View的需要下面這個操作

????????intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

????????

????????PendingIntent?mPendingIntent?=?PendingIntent.getActivity(this,?0,?intent,?0);

????????

????????Notification?mNotification?=?new?Notification();

????????mNotification.icon?=?R.drawable.presence_online;//icon?id

????????mNotification.tickerText?=?"Online";

????????mNotification.defaults?=?Notification.DEFAULT_SOUND?;

????????mNotification.flags?=?Notification.FLAG_AUTO_CANCEL;

????????

????????mNotification.setLatestEventInfo(this,?"QQ",?"Online",?mPendingIntent);

????mNotificationManager.notify(0,?mNotification);

在android手機中,有一個Notification類,這個類從根本上講只是一個記錄我們需要在狀態欄顯示Notification?icon的一些信息,比如:要顯示的Icon的id,led燈閃爍以及閃爍顏色和閃爍時間,讓手機產生振動等。Notification的flag有FLAG_SHOW_LIGHTS,FLAG_AUTO_CANCEL等。有關Notification有三個主要的函數:setLatestEventInfo,notify和cancel

在下面這段代碼中,RemoteViews?是顯示在擴展狀態欄上的,也就是將狀態欄拉下時顯示的Notification,

contentView.setImageViewResource(com.android.internal.R.id.icon,?this.icon)則是將我們設定的icon賦給id為com.android.internal.R.id.icon的ImageView,以便在statusBar中調用顯示。同樣下面都是將本地信息設置為全局信息以便在statusbar中顯示。特別要提一下contentIntent是一個PendingIntent,它負責在點擊Notification時遷移的View。Notification.java:

public?void?setLatestEventInfo(Context?context,

????????????CharSequence?contentTitle,?CharSequence?contentText,?PendingIntent?contentIntent)?{

??RemoteViews?contentView?=?new?RemoteViews(context.getPackageName(),

??????????????com.android.internal.R.layout.status_bar_latest_event_content);

??if?(this.icon?!=?0)?{//實際上就是要顯示的消息對應的icon

??????????contentView.setImageViewResource(com.android.internal.R.id.icon,?this.icon);

??}

??if?(contentTitle?!=?null)?{//Notification對應的title

????????????contentView.setTextViewText(com.android.internal.R.id.title,?contentTitle);

??}

??if?(contentText?!=?null)?{//狀態所對應的下標題

???????????contentView.setTextViewText(com.android.internal.R.id.text,?contentText);

?}

?if?(this.when?!=?0)?{

??????????contentView.setLong(com.android.internal.R.id.time,?"setTime",?when);

?????}

?this.contentView?=?contentView;

?this.contentIntent?=?contentIntent;

}???

那么它是如何顯示到狀態欄上的?

NotificationManager調用Notify函數?:

public?void?notify(String?tag,?int?id,?Notification?notification)

????{

????????int[]?idOut?=?new?int[1];

????????INotificationManager?service?=?getService();

????????String?pkg?=?mContext.getPackageName();

????????if?(localLOGV)?Log.v(TAG,?pkg?+?":?notify("?+?id?+?",?"?+?notification?+?")");

????????try?{

????????????service.enqueueNotificationWithTag(pkg,?tag,?id,?notification,?idOut);

????????????if?(id?!=?idOut[0])?{

????????????????Log.w(TAG,?"notify:?id?corrupted:?sent?"?+?id?+?",?got?back?"?+?idOut[0]);

????????????}

????????}?catch?(RemoteException?e)?{

????????}

????}

最重要的是,在NotificationManagerService.java中,service.enqueueNotificationWithTag(pkg,?tag,?id,?notification,?idOut);它調用NotificationManagerService中方法enqueueNotificationInternal發出聲音振動和燈光,這都只要調用相關的系統服務做就可以了。

以何種方式進行通知狀態欄顯示的?

???if?(notification.icon?!=?0)?{

????????????????StatusBarNotification?n?=?new?StatusBarNotification(pkg,?id,?tag,

????????????????????????r.uid,?r.initialPid,?notification);

????????????????if?(old?!=?null?&&?old.statusBarKey?!=?null)?{

????????????????????r.statusBarKey?=?old.statusBarKey;

????????????????????long?identity?=?Binder.clearCallingIdentity();

????????????????????try?{

????????????????????????mStatusBar.updateNotification(r.statusBarKey,?n);

????????????????????}

????????????????????finally?{

????????????????????????Binder.restoreCallingIdentity(identity);

????????????????????}

????????????????}?else?{

????????????????????long?identity?=?Binder.clearCallingIdentity();

????????????????????try?{

????????????????????????r.statusBarKey?=?mStatusBar.addNotification(n);

????????????????????????mAttentionLight.pulse();

????????????????????}

????????????????????finally?{

????????????????????????Binder.restoreCallingIdentity(identity);

????????????????????}

????????????????}

????????????????sendAccessibilityEvent(notification,?pkg);

在這里調用了statusbarService.java的updateNotification方法,又調用addNotificationViews將icon顯示到狀態欄并顯示相關信息。

updateNotification這個方法中調用addNotificationViews:

//?Construct?the?icon.

????????final?StatusBarIconView?iconView?=?new?StatusBarIconView(this,

????????????????notification.pkg?+?"/0x"?+?Integer.toHexString(notification.id));

????????final?StatusBarIcon?ic?=?new?StatusBarIcon(notification.pkg,?notification.notification.icon,

????????????????????notification.notification.iconLevel,?notification.notification.number);

????????if?(!iconView.set(ic))?{

????????????handleNotificationError(key,?notification,?"Coulding?create?icon:?"?+?ic);

????????????return?null;

????????}

至此,就完成了添加一個icon到Statusbar,同時還有text、title等等。

以DownLoadProvider下載完成后點擊下載的Notification,然后消失Notification為例解釋FLAG_AUTO_CANCEL原因:

在DownLoadProvider這個app中,DownLoadService會創建一個用于更新下載完成Notification的類DownloadNotification,還有一個開啟的線程:updateThread,在這個線程中調用了mNofier.updateNofication(mDownloads.values());然后再DownloadNotification.java中更新下載進度和完成狀態,當下載完成時會在StatusBar上顯示下載完成這個icon。

那么,系統如何維護狀態欄上的Notification呢?也就是如何點擊后取消這個Notification呢?

在StatusBarService下private?class?Launcher?implements?View.OnClickListener

是監聽點擊StatusBarService的函數,當點擊這個Notification時,在void?OnClick()方法中有這樣的callback:mBarService.onNotificationClick(mPkg,?mTag,?mId);

mBarService是這樣定義的:

IStatusBarService?mBarService?=?IStatusBarService.Stub.asInterface(

????????????????ServiceManager.getService(Context.STATUS_BAR_SERVICE));

這就意味著mBarService使用的是StatusbarManagerService.java中定義的接口,如下:

public?interface?NotificationCallbacks?{

????????void?onSetDisabled(int?status);

????????void?onClearAll();

????????void?onNotificationClick(String?pkg,?String?tag,?int?id);

????????void?onPanelRevealed();

????????void?onNotificationError(String?pkg,?String?tag,?int?id,

????????????????int?uid,?int?initialPid,?String?message);

}

onNotificationClick是在NotificationManagerService.java中實現的。因此,當點擊statusbar上的Notification時就調用NotificationManagerService中的這個響應函數:

?public?void?onNotificationClick(String?pkg,?String?tag,?int?id)?{

????????cancelNotification(pkg,?tag,?id,?Notification.FLAG_AUTO_CANCEL,

?????????????????Notification.FLAG_FOREGROUND_SERVICE);

?}

cancelNotification定義如下:

????private?void?cancelNotification(String?pkg,?String?tag,?int?id,?int?mustHaveFlags,

????????????int?mustNotHaveFlags)?{

????????EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL,?pkg,?id,?mustHaveFlags);

????????synchronized?(mNotificationList)?{

????????????int?index?=?indexOfNotificationLocked(pkg,?tag,?id);

????????????if?(index?>=?0)?{

????????????????NotificationRecord?r?=?mNotificationList.get(index);

????????????????if?((r.notification.flags?&?mustHaveFlags)?!=?mustHaveFlags)?{

????????????????????return;

????????????????}

????????????????if?((r.notification.flags?&?mustNotHaveFlags)?!=?0)?{

????????????????????return;

????????????????}

????????????????mNotificationList.remove(index);

????????????????cancelNotificationLocked(r);

????????????????updateLightsLocked();

????????????}

????????}

這就解釋了為什么只有設置Notification?的flag為Notification.FLAG_AUTO_CANCEL才能取消Notification。

總結

以上是生活随笔為你收集整理的Android 4.0 Notification的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。