通知栏Notification的使用
在这一片博客中,小达将自己学习Notification的一些想法和大家分享一哈,学的不是很深,所有有些东西可能解释的不是特别到位,还请各位谅解哈.所谓Notification即
通知,是一种让你的应用程序在不使用Activity的情况下警示用户。它是看不见的程序组件(Broadcast Receiver,Service和不活跃的Activity)
警示用户有需要注意的事件发生的最好途径。后面的一大段一大段是接着前面的项目在继续,大家可以选择性的看一看.
Notification 是由NotificationManager(系统服务)统一管理的。挂在下拉通知栏上面,就像下图所示,
上面显示的都是所谓的Notification,今天我们就来一步步的创建,添加按钮响应,再将Notification和我们的播放器联系起来,话不多说,现在就开始咯.
先给Notification创建了个单独的布局文件,当notification被激活的时候,就在通知栏上面显示这个布局文件的样式,
notification_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/notification_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_photo_01">
<ImageView //显示歌手头像的,,,,,基本没怎么用上,专辑图片不知道怎么弄得出不来
android:id="@+id/notification_artist_image"
android:layout_width="64.0dip"
android:layout_height="64.0dip"
android:background="#00000000"/>
<TextView //在通知栏上显示音乐名称的TextView
android:id="@+id/notification_music_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_marginStart="5.0dp"
android:layout_toRightOf="@+id/notification_artist_image"
android:layout_toEndOf="@+id/notification_artist_image"
android:focusable="true"
android:textColor="#FFADABFF"
android:textSize="18sp"
/>
<TextView<span style="font-family: Arial, Helvetica, sans-serif;"> //在通知栏上显示歌手的TextView</span>
android:id="@+id/notification_music_Artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/notification_music_title"
android:layout_alignStart="@+id/notification_music_title"
android:layout_marginTop="5.0dip"
android:layout_below="@id/notification_music_title"
android:textColor="#FFADABFF"
/>
<ImageButton //通知栏上的退出按钮
android:id="@+id/notification_exit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/notification_exit"
android:layout_below="@+id/notification_music_title"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<ImageButton
android:id="@+id/notification_next_song_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/next_music_photo"
android:layout_toLeftOf="@+id/notification_exit_button"
android:layout_toStartOf="@+id/notification_exit_button"
/>
<ImageButton
android:id="@+id/notification_play_button"
android:layout_toLeftOf="@id/notification_next_song_button"
android:layout_toStartOf="@id/notification_next_song_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"/>
<ImageButton
android:id="@+id/notification_previous_song_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/notification_play_button"
android:layout_toStartOf="@id/notification_play_button"
android:background="@drawable/previous_music_photo"
/>
</RelativeLayout>
布局文件大致弄好了后,就在播放歌曲的同时,直接将这个布局文件显示到通知栏上去,这一步需要Notification和NotificationManager,小达这里是将notification放在了service里面进行操作了,其他地方也可以的,这是service里面的一部分代码,后面会有整个service的代码的,:
private void initMyNotification() {
/*
第一个参数是显示在通知栏上的小图标的图片
第二个参数是在启动notification时,在状态栏上滚动的一句话
第三个参数是在状态栏上显示的时间
*/
myNotification = new Notification(R.drawable.notification_artist_default_image, "小卷毛音乐", System.currentTimeMillis());
/*
NotificationManager用来管理notification的显示和消失等
*/
myNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
/*
对刚才创建的一个notification实例设置各种参数
其中的一个参数是flags
这个参数可以设置该notification是何种状态
这里设置的是ONGOING,表示这个notification会一直呆在通知栏上面
也可以设置滑动后就消失的样式,看个人的不同需求
*/
myNotification.flags = Notification.FLAG_ONGOING_EVENT;
/*
在我们创建的notification中有一个View子类的实例
下面创建了一个RemoteViews的实例
并且配置好各种显示的信息后
将该实例传给notification
往后面看会有一句
myNotification.contentView = contentViews;
这个就是传递实例了
*/
RemoteViews contentViews = new RemoteViews(getPackageName(), R.layout.notification_layout);
contentViews.setImageViewResource
(R.id.notification_artist_image, R.drawable.notification_artist_default_image);
if(mediaPlayer.isPlaying()){
contentViews.setImageViewResource(R.id.notification_play_button,R.drawable.play_photo);
}
else{
contentViews.setImageViewResource(R.id.notification_play_button,R.drawable.pause_photo);
}
/*
将处理好了的一个View传给notification
让其在通知栏上显示
*/
myNotification.contentView = contentViews; /* 在创建的notification中还有一个intent Intent :意图,即告诉系统我要干什么,然后系统根据这个Intent做对应的事。 如startActivity相当于发送消息,而Intent是消息的内容。 PendingIntent :包装Intent,Intent 是我们直接使用 startActivity , startService 或 sendBroadcast 启动某项工作的意图。 而某些时候,我们并不能直接调用startActivity , startServide 或 sendBroadcast ,而是当程序或系统达到某一条件才发送Intent。 如这里的Notification,当用户点击Notification之后,由系统发出一条Activity 的 Intent 。 因此如果我们不用某种方法来告诉系统的话,系统是不知道是使用 startActivity ,startService 还是 sendBroadcast 来启动Intent 的(当然还有其他的“描述”), 因此这里便需要PendingIntent。 PendingIntent.getActivity的参数依次为:Context,发送者的请求码(可以填0),用于系统发送的Intent,标志位 */
</pre><pre name="code" class="java"> Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); myNotification.contentIntent = contentIntent; /* 用notificationManager来启动notification 通过调用notify这个函数来启动 */
myNotificationManager.notify(0, myNotification); }
</pre></div><div style="text-align:left"><span style="font-size:14px"></span></div><div style="text-align:left"><span style="font-size:14px"> 这个函数是一个自定义的初始化函数,需要显示notification的时候直接调用就可以了,里面的注释还是比较详细的,有什么看不懂的地方可以给我留言.</span></div><p></p><p><span style="font-size:14px"> 上面显示出来的Notification只能看,上面有几个按钮还不能点击,在这个上面的按钮点击监听器和普通的有点区别,由于notification经常和activity独立的存在,没有什么直接的关联,需要通过broadcast机制来互相传递信息,notification上的按钮点击之后,会发送一个指定了的广播,只需要接收后再做处理,就能达到按钮监听器的效果了,在notification上面按钮点击需要简单的三个步骤:</span></p><p><span style="font-size:14px"> 第一步: 实例化一个intent,作为发送广播的intent,里面存放action,也就是需要传递给activity或者service的提示信息.</span></p><p><span style="font-size:14px"></span><pre name="code" class="java"> Intent previousButtonIntent = new Intent(NotificationMsg.NOTIFICATION_PREVIOUS_MUSIC);
第二步: 实例化一个PendingIntent,把上面的intent包装起来,并说明是用来发广播的intent,
PendingIntent pendPreviousButtonIntent = PendingIntent.getBroadcast(this, 0, previousButtonIntent, 0);
contentViews.setOnClickPendingIntent(R.id.notification_previous_song_button, pendPreviousButtonIntent);
有没有很快,,,,这样点击之后就可以发送一个广播出去了,再怎么接受纯属个人喜好问题了哈.....
下面是service的源码,好像有点长额,重点看红色的地方,是关于notification的:
package com.example.dada.myapplication;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.view.animation.AnimationUtils;
import android.widget.RemoteViews;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class PlayerService extends Service implements AppConstant {
private int current_position;
private String musicPath;
private String music_artist;
private String music_title;
<span style="color:#ff0000;"> private String notification_msg;</span>
private boolean isPause = true;
private boolean isChangToNext;
<span style="color:#ff0000;"> private NotificationManager myNotificationManager; //通知栏
private Notification myNotification;</span>
private ChangeToNextReceiver changeToNextReceiver;
private PlayReceiver playReceiver;
private ProgressChangeReceiver progressChangeReceiver;
public static MediaPlayer mediaPlayer = new MediaPlayer();
private Intent intent_to_activity = new Intent("com.example.communication.RECEIVER");
private Intent intent_to_progressBar = new Intent("com.example.communication.BAR");
<span style="color:#ff0000;"> private Intent notification_to_activity = new Intent("com.example.communication.NOTIFICATION_TO_ACTIVITY");</span>
private Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == PlayerMsg.PLAY_MSG) {
current_position = mediaPlayer.getCurrentPosition();
intent_to_progressBar.putExtra("position", current_position);
sendBroadcast(intent_to_progressBar);
myHandler.sendEmptyMessageDelayed(PlayerMsg.PLAY_MSG, 1000);
}
if (msg.what == PlayerMsg.PAUSE) {
stopMusic();
}
}
};
@Override
public IBinder onBind(Intent intent) {
return null;
}
public int onStartCommand(Intent intent, int flags, int startId) {
notification_msg = null;
playReceiver = new PlayReceiver();
changeToNextReceiver = new ChangeToNextReceiver();
progressChangeReceiver = new ProgressChangeReceiver();
IntentFilter intentChangeFilter = new IntentFilter();
IntentFilter intentPlayFilter = new IntentFilter();
IntentFilter intentProgressChangeFilter = new IntentFilter();
intentChangeFilter.addAction("com.example.communication.ChANGE_MUSIC");
intentPlayFilter.addAction("com.example.communication.PLAY");
intentProgressChangeFilter.addAction("com.example.communication.PROGRESS_BAR");
<span style="color:#ff0000;">
IntentFilter previousMusicFilter = new IntentFilter();
previousMusicFilter.addAction(NotificationMsg.NOTIFICATION_PREVIOUS_MUSIC);
registerReceiver(onClickReceiver, previousMusicFilter);
IntentFilter nextMusicFilter = new IntentFilter();
nextMusicFilter.addAction(NotificationMsg.NOTIFICATION_NEXT_MUSIC);
registerReceiver(onClickReceiver,nextMusicFilter);
IntentFilter pauseMusicFilter = new IntentFilter();
pauseMusicFilter.addAction(NotificationMsg.NOTIFICATION_PAUSE_MUSIC);
registerReceiver(onClickReceiver,pauseMusicFilter);
IntentFilter exitFilter = new IntentFilter();
exitFilter.addAction(NotificationMsg.NOTIFICATION_EXIT);
registerReceiver(onClickReceiver,exitFilter);</span>
<span style="color:#ff0000;"> registerReceiver(playReceiver, intentPlayFilter);
registerReceiver(changeToNextReceiver, intentChangeFilter);
registerReceiver(progressChangeReceiver, intentProgressChangeFilter);</span>
try {
int msg = intent.getIntExtra("MSG", 0);
musicPath = intent.getStringExtra("url");
SendBroadcastToActivity(intent);
if (msg == AppConstant.PlayerMsg.PLAY_MSG) {
myHandler.sendEmptyMessage(PlayerMsg.PLAY_MSG);
playMusic(0);
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
private void playMusic(int position) {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(musicPath);
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(new MyPreparedListener(position));
<span style="color:#ff0000;"> initMyNotification();</span>
} catch (IOException e) {
e.printStackTrace();
}
}
private class MyPreparedListener implements MediaPlayer.OnPreparedListener {
private int position;
public MyPreparedListener(int position) {
this.position = position;
}
public void onPrepared(MediaPlayer mp) {
if (position > 0)
mediaPlayer.seekTo(position);
mediaPlayer.start();
}
}
private void stopMusic() {
if (mediaPlayer != null) {
mediaPlayer.pause();
}
}
public void onDestory() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
private void SendBroadcastToActivity(Intent intent) { //向activity发送广播的函数
music_title = intent.getStringExtra("title");
music_artist = intent.getStringExtra("artist");
<span style="color:#ff0000;"> initMyNotification();</span>
intent_to_activity.putExtra("title", intent.getStringExtra("title"));
intent_to_activity.putExtra("artist", intent.getStringExtra("artist"));
intent_to_activity.putExtra("album", intent.getStringExtra("album"));
intent_to_activity.putExtra("album_id", intent.getLongExtra("album_id", 0));
sendBroadcast(intent_to_activity);
}
private class PlayReceiver extends BroadcastReceiver { //播放与暂停广播接收器
public PlayReceiver() {
super();
}
@Override
public void onReceive(Context context, Intent intent) {
isPause = intent.getBooleanExtra("isPause", true);
isChangToNext = intent.getBooleanExtra("isChangeToNext", false);
if (isPause) {
myHandler.sendEmptyMessage(PlayerMsg.PAUSE);
} else {
current_position = intent.getIntExtra("position", 0);
playMusic(current_position);
myHandler.sendEmptyMessage(PlayerMsg.PLAY_MSG);
}
}
}
private class ChangeToNextReceiver extends BroadcastReceiver { //换歌广播接收器
public ChangeToNextReceiver() {
super();
}
@Override
public void onReceive(Context context, Intent intent) {
isChangToNext = intent.getBooleanExtra("isChangeToNext", false);
if (isChangToNext) {
musicPath = intent.getStringExtra("music_url");
music_artist = intent.getStringExtra("music_artist");
music_title = intent.getStringExtra("music_title");
playMusic(0);
<span style="color:#ff0000;"> initMyNotification();</span>
}
}
}
private class ProgressChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
current_position = intent.getIntExtra("current_position", 0);
playMusic(current_position);
}
}
<span style="color:#ff0000;"> private void initMyNotification() {
/*
第一个参数是显示在通知栏上的小图标的图片
第二个参数是在启动notification时,在状态栏上滚动的一句话
第三个参数是在状态栏上显示的时间
*/
myNotification = new Notification(R.drawable.notification_artist_default_image, "小卷毛音乐", System.currentTimeMillis());
/*
NotificationManager用来管理notification的显示和消失等
*/
myNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
/*
对刚才创建的一个notification实例设置各种参数
其中的一个参数是flags
这个参数可以设置该notification是何种状态
这里设置的是ONGOING,表示这个notification会一直呆在通知栏上面
也可以设置滑动后就消失的样式,看个人的不同需求
*/
myNotification.flags = Notification.FLAG_ONGOING_EVENT;
/*
在我们创建的notification中有一个View子类的实例
下面创建了一个RemoteViews的实例
并且配置好各种显示的信息后
将该实例传给notification
往后面看会有一句
myNotification.contentView = contentViews;
这个就是传递实例了
*/
RemoteViews contentViews = new RemoteViews(getPackageName(), R.layout.notification_layout);
contentViews.setImageViewResource
(R.id.notification_artist_image, R.drawable.notification_artist_default_image);
contentViews.setTextViewText(R.id.notification_music_title, music_title);
contentViews.setTextViewText(R.id.notification_music_Artist, music_artist);
if(mediaPlayer.isPlaying()){
contentViews.setImageViewResource(R.id.notification_play_button,R.drawable.play_photo);
}
else{
contentViews.setImageViewResource(R.id.notification_play_button,R.drawable.pause_photo);
}
/*
将处理好了的一个View传给notification
让其在通知栏上显示
*/
myNotification.contentView = contentViews;
Intent previousButtonIntent = new Intent(NotificationMsg.NOTIFICATION_PREVIOUS_MUSIC);
PendingIntent pendPreviousButtonIntent = PendingIntent.getBroadcast(this, 0, previousButtonIntent, 0);
contentViews.setOnClickPendingIntent(R.id.notification_previous_song_button, pendPreviousButtonIntent);
Intent nextButtonIntent = new Intent(NotificationMsg.NOTIFICATION_NEXT_MUSIC);
PendingIntent pendNextButtonIntent = PendingIntent.getBroadcast(this, 0, nextButtonIntent, 0);
contentViews.setOnClickPendingIntent(R.id.notification_next_song_button, pendNextButtonIntent);
Intent playButtonIntent = new Intent(NotificationMsg.NOTIFICATION_PAUSE_MUSIC);
PendingIntent pendPlayButtonIntent = PendingIntent.getBroadcast(this, 0, playButtonIntent, 0);
contentViews.setOnClickPendingIntent(R.id.notification_play_button, pendPlayButtonIntent);
Intent exitButton = new Intent(NotificationMsg.NOTIFICATION_EXIT);
PendingIntent pendingExitButtonIntent = PendingIntent.getBroadcast(this,0,exitButton,0);
contentViews.setOnClickPendingIntent(R.id.notification_exit_button,pendingExitButtonIntent);
/*
在创建的notification中还有一个intent
Intent :意图,即告诉系统我要干什么,然后系统根据这个Intent做对应的事。
如startActivity相当于发送消息,而Intent是消息的内容。
PendingIntent :包装Intent,Intent 是我们直接使用 startActivity , startService 或 sendBroadcast 启动某项工作的意图。
而某些时候,我们并不能直接调用startActivity , startServide 或 sendBroadcast ,而是当程序或系统达到某一条件才发送Intent。
如这里的Notification,当用户点击Notification之后,由系统发出一条Activity 的 Intent 。
因此如果我们不用某种方法来告诉系统的话,系统是不知道是使用 startActivity ,startService 还是 sendBroadcast 来启动Intent 的(当然还有其他的“描述”),
因此这里便需要PendingIntent。
PendingIntent.getActivity的参数依次为:Context,发送者的请求码(可以填0),用于系统发送的Intent,标志位
*/
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
myNotification.contentIntent = contentIntent;
/*
用notificationManager来启动notification
通过调用notify这个函数来启动
*/
myNotificationManager.notify(0, myNotification);
}</span>
<span style="color:#ff0000;">BroadcastReceiver onClickReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Boolean notification_previous_music = false;
Boolean notification_next_music = false;
Boolean notification_pause_music = false;
Boolean notification_exit = false;
notification_msg = intent.getAction();
if (notification_msg.equals(NotificationMsg.NOTIFICATION_PREVIOUS_MUSIC)) {
notification_previous_music = true;
}
if(notification_msg.equals(NotificationMsg.NOTIFICATION_NEXT_MUSIC)){
notification_next_music = true;
}
if(notification_msg.equals(NotificationMsg.NOTIFICATION_PAUSE_MUSIC)){
if(mediaPlayer.isPlaying()){
notification_pause_music = true;
initMyNotification();
stopMusic();
}
else{
playMusic(current_position);
initMyNotification();
}
}
if(notification_msg.equals(NotificationMsg.NOTIFICATION_EXIT)){
notification_exit = true;
myNotificationManager.cancelAll();
}
notification_to_activity.putExtra("notification_previous_music",notification_previous_music);
notification_to_activity.putExtra("notification_next_music",notification_next_music);
notification_to_activity.putExtra("notification_pause_music",notification_pause_music);
notification_to_activity.putExtra("notification_exit",notification_exit);
sendBroadcast(notification_to_activity);
}
};</span>
}
上面在notification的按钮点击之后,先在service里面做了处理,然后再发广播通知activity做出相应的处理.(
<span style="color:#ff0000;">sendBroadcast(notification_to_activity);</span>)
在activity中的部分代码如下:
private boolean notification_previous_music; //通知栏上一首
private boolean notification_next_music; //通知栏下一首
private boolean notification_pause_music; //通知栏停止播放
private boolean notification_exit; //通知栏退出
private NotificationReceiver notificationReceiver; //通知栏广播接收器
notificationReceiver = new NotificationReceiver();
IntentFilter intentNotificationFilter = new IntentFilter();
intentNotificationFilter.addAction("com.example.communication.NOTIFICATION_TO_ACTIVITY");
registerReceiver(notificationReceiver,intentNotificationFilter);
private class NotificationReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
notification_previous_music = intent.getBooleanExtra("notification_previous_music",false);
notification_next_music = intent.getBooleanExtra("notification_next_music",false);
notification_pause_music = intent.getBooleanExtra("notification_pause_music",false);
notification_exit = intent.getBooleanExtra("notification_exit",false);
if(notification_previous_music){
changeMusic(play_mode,AppConstant.PlayerMsg.PREVIOUS_MUSIC,mp3Infos);
}
if(notification_next_music){
changeMusic(play_mode,AppConstant.PlayerMsg.NEXT_MUSIC,mp3Infos);
}
if(notification_pause_music){
play_button.setImageResource(R.drawable.play_photo);
}
else{
play_button.setImageResource(R.drawable.pause_photo);
}
if(notification_exit){
System.exit(0);
}
}
}
代码很简单,读读就能懂哈,这篇给的代码有点长了,主要介绍的notification的用法,后面的一大段一大段是接着前面的项目在继续,大家可以选择性的看一看.
在下一期博客中,我们将介绍android上的数据库使用,记录最近播放的音乐,也差不多快到尾声了,这个小系列从2014年写到了2015年,估计是最长时间的了,,,23333.今天就写到这里咯,明天见~~~~~88