通知栏notification是Android中一个很重要的组件,可以在顶部状态栏中存在,用户也可以通过此来操作应用,在Android中只有3.0以上的版本才加入了notification的按钮点击功能。
先看一下仿虾米写出来的通知的效果
这是一个自定义的notification,添加了,前一曲、播放、暂停、下一曲等功能,自定义的notification需要自己写布局文件,并通过remoteview显示在界面中。
res/layout/customnotice.xml
写了布局之后就需要实例化通知了
1.定义一个NotificationManager对象,并实例化
2.定义一个RemoteViews对象
3.设置RemoteViews属性
private NotificationManager manager;
private RemoteViews remoteViews;
manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
/**
* 设置通知
*/
@SuppressLint("NewApi")
private void setNotification() {
NotificationCompat.Builder builder = new Builder(this);
Intent intent = new Intent(this, MainActivity.class);
// 点击跳转到主界面
PendingIntent intent_go = PendingIntent.getActivity(this, 5, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.notice, intent_go);
// 4个参数context, requestCode, intent, flags
PendingIntent intent_close = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_close, intent_close);
// 设置上一曲
Intent prv = new Intent();
prv.setAction(Constants.ACTION_PRV);
PendingIntent intent_prev = PendingIntent.getBroadcast(this, 1, prv,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_prev, intent_prev);
// 设置播放
if (Myapp.isPlay) {
Intent playorpause = new Intent();
playorpause.setAction(Constants.ACTION_PAUSE);
PendingIntent intent_play = PendingIntent.getBroadcast(this, 2,
playorpause, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_play, intent_play);
}
if (!Myapp.isPlay) {
Intent playorpause = new Intent();
playorpause.setAction(Constants.ACTION_PLAY);
PendingIntent intent_play = PendingIntent.getBroadcast(this, 6,
playorpause, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_play, intent_play);
}
// 下一曲
Intent next = new Intent();
next.setAction(Constants.ACTION_NEXT);
PendingIntent intent_next = PendingIntent.getBroadcast(this, 3, next,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_next, intent_next);
// 设置收藏
PendingIntent intent_fav = PendingIntent.getBroadcast(this, 4, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widget_fav, intent_fav);
builder.setSmallIcon(R.drawable.notification_bar_icon); // 设置顶部图标
Notification notify = builder.build();
notify.contentView = remoteViews; // 设置下拉图标
notify.bigContentView = remoteViews; // 防止显示不完全,需要添加apisupport
notify.flags = Notification.FLAG_ONGOING_EVENT;
notify.icon = R.drawable.notification_bar_icon;
manager.notify(100, notify);
}
PendingIntent是一种特殊的intent,设置之后并不会马上使用,而是在真正点击后只会调用。Android默认使用的通知高度大概是64dp,无法满足大界面的显示,所以需要在其中设置bigContentView,这样才能显示大图。manager.notify(id, notification)中第一个参数是一个标识码,在取消通知的时候需要传入这个参数,第二个就是一个notify对象。
通知栏一次实例化后里面按钮的点击事件就确定了,如果当前设置的是播放的按钮,那么暂停是不会起作用的,所以需要重新设置通知,目前采用的是用Handler来更新通知栏。
public Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
Mp3Info info = (Mp3Info) msg.obj;
Bitmap bitmap = MediaUtil.getArtwork(getApplicationContext(),
info.getId(), info.getAlbumId(), true, false);
btm_album.setImageBitmap(bitmap);
btm_artist.setText(info.getArtist());
btm_title.setText(info.getTitle());
// 播放歌曲
btm_state
.setImageResource(R.drawable.player_btn_radio_pause_normal);
// 设置通知栏的图片文字
remoteViews = new RemoteViews(getPackageName(),
R.layout.customnotice);
remoteViews.setImageViewBitmap(R.id.widget_album, bitmap);
remoteViews.setTextViewText(R.id.widget_title, info.getTitle());
remoteViews.setTextViewText(R.id.widget_artist, info.getArtist());
if (Myapp.isPlay) {
remoteViews.setImageViewResource(R.id.widget_play, R.drawable.widget_btn_pause_normal);
}else {
remoteViews.setImageViewResource(R.id.widget_play, R.drawable.widget_btn_play_normal);
}
setNotification();
};
};
在退出的时候需要取消通知栏,用NotificationManager的manager对象取消通知view,其中的100是notify设置的id,用来区别通知,因为在其他应用中可能会产生好多通知。
@Override
protected void onDestroy() {
Log.i("---"+TAG, "ondestory");
super.onDestroy();
if (remoteViews != null) {
manager.cancel(100);
}
if (receiver != null) {
unregisterReceiver(receiver);
}
}