用到的类和方法
NotificationManager // notification 管理类 由他来发送通知 和 取消通知
Notification // 通知
NotificationCompat.Builder // 通知 的builder 和 提示框的builder类似
RemoteViews // 用布局文件填充出来 然后将它添加给notification 实现通知栏自定义view的功能
PendingIntent //用于 通知栏 被点击后 要发送的intent
效果图: 音乐播放控制栏
首先 看一下默认的通知栏 和 自定通知栏
自定义可以添加按键这些比较好!!!
默认通知栏实现代码
步骤:
1、创建一个intent 用于 通知栏被点击的时候 要发送的intent 意图:可以启动activity service broadcastReceiver等等
2、将 用上面的intent 构建出一个PendingIntent , 这个pendingIntent 对intent 进行了一些参数的设置 如:点击的时候是 只发送一次 还是每次点击都发送等等。。 后面会将它设置给 notification
3、创建一个NotificationCompat.Builder 用对它进行一些参数的设置 然后用它构建出一个 notification
4、buidler.buidle()出一个notification
5、获取 notificationManager 管理器 由他的 notify() 和cancel()方法 发送或者取消通知
public void initNormalNotification(){ // 通知 和 对话框的 创建过程差不多 // 当点击 通知的时候 可以发送intent 来通知广播 activity service等等 manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); Intent intent = new Intent(this,MyBroadcastReceiver.class); intent.putExtra("value",88); // arg0:context arg1:requestCode arg2:intent // arg3:发送intent的模式 每次点击都发送 还有很多其他模式 PendingIntent mPendingIntent = PendingIntent.getBroadcast(this,1,intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setSmallIcon(R.drawable.notification_music_playing)//图标 .setTicker("我是ticker")//通知开始的时候 一闪而过的提示内容 .setWhen(System.currentTimeMillis()) // 设置发送通知的 时间 .setOngoing(true) //是否一直停留在通知栏 有很多种模式 .setContentTitle("我是标题") .setContentText("我是内容") .setContentIntent(mPendingIntent); //通知栏 被点击 时候 要发送的 附带的intent mNormalNotification = builder.build(); //创建 notification对象 } //显示 notification public void showNormalNotification(){ //arg0: notification的唯一标识 manager.notify(1, mNormalNotification); // manager.cancel(1); //通过唯一标识移除 通知 }
下面是自定义的 通知栏
步骤差不多:
首先 创建一个RemoteView
然后 将它设置给 builder .setContent(getRemoteView());// 添加一个自定view(RemoteView)
通过 设置RemoteView的 控件来实现事件的监听和交互
//初始化 自定义的 通知 public void initCustomNotification(){ // 通知 和 对话框的 创建过程差不多 // 当点击 通知的时候 可以发送intent 来通知广播 activity service等等 manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setSmallIcon(R.drawable.notification_music_playing)//图标 .setTicker("我是ticker")//通知开始的时候 一闪而过的提示内容 .setWhen(System.currentTimeMillis()) // 设置发送通知的 时间 .setOngoing(true) //是否一直停留在通知栏 有很多种模式 .setContent(getRemoteView()); // 添加一个自定view (RemoteView) //创建 notification对象 mCustomNotification = builder.build(); }//创建一个remoteView 用来填充 通知的布局 public RemoteViews getRemoteView(){ //填充一个RemoteViews mRemoteViews = new RemoteViews(getPackageName(), R.layout.notification_item_layout); mRemoteViews.setTextViewText(R.id.tv_title,"我是自定义标题"); mRemoteViews.setTextViewText(R.id.tv_content,"我是自定义内容"); //给 自定义布局上的控件 设置点击了发送 pendingIntent 类似于监听器 // 这里我都是去 发送 一个serviceIntent 在service里面获取Intent在的参数 以判断来自哪一个按键 Intent preIntent = new Intent(this,MyService.class); preIntent.putExtra("what",1); // arg0:context arg1:requestCode arg2:intent arg3:发送intent的模式 每次点击都发送 还有很多其他模式 PendingIntent prePendingIntent = PendingIntent.getService(this,1,preIntent,PendingIntent.FLAG_UPDATE_CURRENT); mRemoteViews.setOnClickPendingIntent(R.id.bt_playPre,prePendingIntent); //设置点击时要发送的intent Intent playIntent = new Intent(this,MyService.class); playIntent.putExtra("what",2); PendingIntent playPendingIntent = PendingIntent.getService(this,5,playIntent,PendingIntent.FLAG_UPDATE_CURRENT); mRemoteViews.setOnClickPendingIntent(R.id.bt_PlayOrPause,playPendingIntent); //设置点击时要发送的intent Intent NextIntent = new Intent(this,MyService.class); NextIntent.putExtra("what",3); PendingIntent nextPendingIntent = PendingIntent.getService(this,7,NextIntent,PendingIntent.FLAG_UPDATE_CURRENT); mRemoteViews.setOnClickPendingIntent(R.id.bt_playNext,nextPendingIntent); //设置点击时要发送的intent return mRemoteViews; }
//设置 remoteView中控件的属性 public void setViewTitleContext(String title,String content){ mRemoteViews.setTextViewText(R.id.tv_title,title); mRemoteViews.setTextViewText(R.id.tv_content,content); } public void showCustomNotification(){ //arg0: notification的唯一标识 manager.notify(2, mCustomNotification); // manager.cancel(2); //通过唯一标识移除 通知 }
分析一下这几句
mRemoteViews.setTextViewText(R.id.tv_title,"我是自定义标题");
设置 自定义控件中 id 为R.id.tv_title的文字内容
Intent preIntent = new Intent(this,MyService.class);
preIntent.putExtra("what",1);
PendingIntent prePendingIntent = PendingIntent.getService(this,1,preIntent,PendingIntent.FLAG_UPDATE_CURRENT);
mRemoteViews.setOnClickPendingIntent(R.id.bt_playPre,prePendingIntent); //设置点击时要发送的intent
可以看出 当R.id.bt_playPre 按键被点击的时候发送一个 intent 启动 一个MyService的 服务。
我们还设置了一个 “what ” 值 这个是自己定义的 那么多intent 去启动同一个service 谁知道是哪一个intent 可以通过获取该值来判断
mRemoteViews.setOnClickPendingIntent(R.id.bt_playPre,prePendingIntent); //设置点击时要发送的intent
就是设置 当R.id.bt_playPre 按键被点击的时候发送一个 intent 启动 一个MyService的 服务。
注意:如果更改了remoteView中的 内容 必须
manager.notify(2, mCustomNotification);
否则,内容 无法更新
下面是被启动service的内容
public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { switch(intent.getIntExtra("what",8)){ case 1: Toast.makeText(this,"服务 收到点击了 上一曲", Toast.LENGTH_LONG).show(); break; case 2: Toast.makeText(this,"服务 收到点击了 播放", Toast.LENGTH_LONG).show(); break; case 3: Toast.makeText(this,"服务 收到点击了 下一曲", Toast.LENGTH_LONG).show(); break; } return super.onStartCommand(intent, flags, startId); } }
工作顺利!生活愉快!
学一点记录一点!