1. 实例FM的notification
/**
* Show notification
*/
private void showNotification() {
Intent notificationIntent = new Intent();
notificationIntent.setClassName(getPackageName(), FmRadioActivity.class.getName());
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
Notification notification = new Notification(R.drawable.fm_title_icon, null, System.currentTimeMillis());
notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
String fmUnit = mContext.getString(R.string.fm_unit);
String text = FmRadioUtils.formatStation(mCurrentStation) + " " + fmUnit;
notification.setLatestEventInfo(getApplicationContext(),getResources().getString(R.string.app_name), text, pendingIntent);
Log.d(TAG, "Add notification to the title bar.");
startForeground(NOTIFICATION_ID, notification);
}
//转台之后需要update,就是重新加载下
private void updateNotification() {
Log.d(TAG, "FmRadioService.updateNotification");
if (mIsPowerUp) {
showNotification();
}
}
//关闭FM时,也要关闭相应的notification
private void removeNotification() {
Log.d(TAG, "FmRadioService.removeNotification");
stopForeground(true);
}
2. Music 的Notification
private void updateNotification(Context context, Bitmap bitmap) {
RemoteViews views = new RemoteViews(getPackageName(), R.layout.newstatusbar);
String trackinfo = getTrackName();
String artist = getArtistName();
if (artist == null || artist.equals(MediaStore.UNKNOWN_STRING)) {
artist = getString(R.string.unknown_artist_name);
}
Resources res = getResources();
int textColor = res.getThemeMainColor();
if (textColor != 0) {
views.setTextColor(R.id.txt_trackinfo, textColor);
}
trackinfo += " - " + artist;
views.setTextViewText(R.id.txt_trackinfo, trackinfo);
Intent intent;
PendingIntent pIntent;
intent = new Intent("com.android.music.PLAYBACK_VIEWER");
intent.putExtra("collapse_statusbar", true);
pIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.iv_cover, pIntent);
intent = new Intent(PREVIOUS_ACTION);
intent.setClass(context, MediaPlaybackService.class);
pIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.btn_prev, pIntent);
intent = new Intent(PAUSE_ACTION);
intent.setClass(context, MediaPlaybackService.class);
pIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.btn_pause, pIntent);
intent = new Intent(NEXT_ACTION);
intent.setClass(context, MediaPlaybackService.class);
pIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.btn_next, pIntent);
intent = new Intent("my.nullaction");
pIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.rl_newstatus, pIntent);
if (bitmap != null) {
views.setImageViewBitmap(R.id.iv_cover, bitmap);
mAlbumArt = bitmap;
}
intent = new Intent("com.android.music.PLAYBACK_VIEWER");
Notification status = new Notification();
/*Add by dongyang.li Begin: modified 添加修改代码*/
//status_icon 为状态栏图标,R.id.statusbar_pause 为通知 的 暂停/开始按钮
int status_icon = R.drawable.ic_appwidget_music_pause;
//根据播放状态,来决定 暂停/开始 图标
if(isPlaying()){
views.setImageViewResource(R.id.status_pause, R.drawable.ic_appwidget_music_pause);
}else{
views.setImageViewResource(R.id.status_pause, R.drawable.ic_appwidget_music_play);
status_icon = R.drawable.ic_appwidget_music_pause;
}
//给通知栏 暂停/开始 按钮 添加点击事件
views.setOnClickPendingIntent(R.id.status_pause, pause_PendingIntent());
/*End: */
status.contentView = views;
status.flags |= Notification.FLAG_ONGOING_EVENT;
//status.icon = R.drawable.stat_notify_musicplayer;
status.icon = status_icon;
status.contentIntent = PendingIntent.getActivity(context, 0, intent, 0);
mMediaplayerHandler.removeMessages(DEALY_STOPFORGROUND);
startForeground(PLAYBACKSERVICE_STATUS, status);
}
private PendingIntent pause_PendingIntent(){
Intent intent = new Intent(TOGGLEPAUSE_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
return pendingIntent;
}
Notification除了用于后台服务通知,还常用在下面情况:
(1)保持服务存在。当系统内存不足时,系统会认为某后台服务占用内存时间太长而中止该服务,以释放内存。对于某些服务,例如播放音乐,如果系统对该服务进行资源释放,用户体验就成了音乐突然没有声音。对这类服务,我们希望享有更高的优先级别,不会被系统干掉。
(2)用户随时与服务进行互动。例如播放音乐的服务,用户可随时暂停音乐播放,或选择其他曲目,甚至中止播放音乐服务。
要实现上述两点,方法是在Service中宣称自己是foreground,并维持一个通知来向用户表明foreground状态,用户可以通过下拉通知并点击通知,进入该服务界面,实施互动操作。
//设置notification的flag,表明在点击通知后,通知并不会消失,也在最右图上仍在通知栏显示图标。这是确保在activity中退出后,状态栏仍有图标可提下拉、点击,再次进入activity。
myNotify.flags |= Notification.FLAG_NO_CLEAR;
startForeground( NOTIFY_FAKEPLAYER_ID, myNotify);
根据activity的生命周期,在activity不显示时,会执行onStop函数(比如按下home键),所以你在onStop函数(按退出键除外)里面把notification放在通知栏里,再此显示时,把notification从通知栏里去掉。或者,只要程序在运行就一直显示通知栏图标。
下面对Notification类中的一些常量,字段,方法简单介绍一下:
常量:
DEFAULT_ALL 使用所有默认值,比如声音,震动,闪屏等等
DEFAULT_LIGHTS 使用默认闪光提示
DEFAULT_SOUNDS 使用默认提示声音
DEFAULT_VIBRATE 使用默认手机震动
【说明】:加入手机震动,一定要在manifest.xml中加入权限:
<uses-permission android:name=
"android.permission.VIBRATE"
/>
以上的效果常量可以叠加,即通过
notification.defaults =DEFAULT_SOUND|DEFAULT_VIBRATE;
notification.defaults |= DEFAULT_SOUND (最好在真机上测试,震动效果模拟器上没有)
//设置flag位
FLAG_AUTO_CANCEL 该通知能被状态栏的清除按钮给清除掉
FLAG_NO_CLEAR 该通知能被状态栏的清除按钮给清除掉
FLAG_ONGOING_EVENT 通知放置在正在运行
FLAG_INSISTENT 是否一直进行,比如音乐一直播放,知道用户响应
常用字段:
contentIntent 设置PendingIntent对象,点击时发送该Intent
defaults 添加默认效果
flags 设置flag位,例如FLAG_NO_CLEAR等
icon 设置图标
sound 设置声音
tickerText 显示在状态栏中的文字
when 发送此通知的时间戳
NotificationManager常用方法介绍:
public
void
cancelAll() 移除所有通知(只是针对当前Context下的Notification)
public
void
cancel(
int
id) 移除标记为id的通知 (只是针对当前Context下的所有Notification)
public
void
notify(String tag ,
int
id, Notification notification) 将通知加入状态栏,标签为tag,标记为id
public
void
notify(
int
id, Notification notification) 将通知加入状态栏,标记为id
知识点
1)什么是PendingIntent
PendingIntent和Intent略有不同,它可以设置执行次数,主要用于远程服务通信、闹铃、通知、启动器、短信中,在一般情况下用的比较少。
2)PendingIntent什么用
Notification支持多种Intent来响应单击事件、消除事件、处理紧急状态的全屏事件等。
这里就用到了setContentIntent(PendingIntent intent)来处理以上这么多的事件。
3)相关属性和方法
属性:
PendingIntent的位标识符:
FLAG_ONE_SHOT 表示返回的PendingIntent仅能执行一次,执行完后自动取消
FLAG_NO_CREATE 表示如果描述的PendingIntent不存在,并不创建相应的PendingIntent,而是返回NULL
FLAG_CANCEL_CURRENT 表示相应的PendingIntent已经存在,则取消前者,然后创建新的PendingIntent,这个有利于数据保持为最新的,可以用于即时通信的通信场景
FLAG_UPDATE_CURRENT 表示更新的PendingIntent
方法:
可以看出,它支持多种相应方式,有Activity、Broadcast、Service,就根据你自身需求去选择。
在各种情况下情况下它还会根据各种情况出发效果:
contentIntent:在通知窗口区域,Notification被单击时的响应事件由该intent触发;
deleteIntent:当用户点击全部清除按钮时,响应该清除事件的Intent;
fullScreenIntent:响应紧急状态的全屏事件(例如来电事件),也就是说通知来的时候,跳过在通知区域点击通知这一步,直接执行fullScreenIntent代表的事件。
例如:在执行了点击通知之后要跳转到指定的XXX的Activity的时候,可以设置以下方法来相应点击事件:
- Intent intent = new Intent(context,XXX.class);
- PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
- mBuilder.setContentIntent(pendingIntent)
例如:在执行了清空全部的通知操作时候,可以设置以下方法来相应这个事件:
采用setDeleteIntent(PendingIntent intent)方法或按照以下写法
- Intent deleteIntent = new Intent();
- deleteIntent.setClass(context, XXXReceiver.class);
- deleteIntent.setAction(DELETE_ACTION);
- notification.deleteIntent = PendingIntent.getBroadcast(context, 0, deleteIntent, 0);
例如:在响应紧急事件(如来电)时候,可以设置以下方法来相应这个事件:
采用setFullScreenIntent(PendingIntent intent, boolean highPriority)
具体的Notification配置,可参考
http://www.cnblogs.com/newcj/archive/2011/03/14/1983782.html