Notification和Activity交互
概述
通知(Notification)就是程序在不影响用户操作的情况下,通过手机顶部弹出消息告诉用户的一种信息通知方式,而且能够通过下拉通知操作抽屉通知,实现Notification与活动、通知和服务通信。比如:通知与活动相互通信,活动通过NotificationManager发送通知(创建通知),而抽屉通知里面的操作则通过发送广播事件传递信息,此时活动仅仅要已经注冊过该广播事件的接收器,那么就能接收到通知的信息,从而实现通知和活动交互。
样例(通知和活动同步音乐播放和暂停)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/bg" android:scaleType="fitXY"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/play_over" android:layout_gravity="center" android:clickable="true" android:id="@+id/imageView" android:background="@drawable/img_bg"/> </FrameLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="64dp" android:background="#e0e0e0" android:orientation="horizontal"> <ImageView android:id="@+id/imageView1" android:layout_width="64dp" android:layout_height="64dp" android:src="@drawable/sc"/> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image_control" android:clickable="true" android:padding="4dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_width="48dp" android:layout_height="48dp" android:src="@drawable/play_over"/> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/image_control" android:padding="4dp" android:text="Sweet Child O' Mine" android:singleLine="true" android:textAppearance="?android:attr/textAppearanceMedium"/> <TextView android:id="@+id/tv_nowTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/image_control" android:text="00:00" android:layout_alignParentBottom="true"/> <TextView android:id="@+id/tv_totallTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:text="00:00"/> </RelativeLayout> </LinearLayout>
package com.liujun.activity; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import com.liujun.liujunmusicnotification.R; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.media.MediaPlayer; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.RemoteViews; public class MainActivity extends Activity { private MediaPlayer mediaPlayer;//媒体播放器 private NotificationManager notificationManager;//通知管理器 private ImageView imageView;//播放音乐图片button private boolean isPlaying=false;//是否正在播放音乐 //意图 public static final String PLAYMUSIC_INTENT="PLAYMUSIC_INTENT"; public static final String PAUSEMUSIC_INTENT="PAUSEMUSIC_INTENT"; //通知标识ID public static final int NOTIFICATION_ID=1; //时间计时器 private Timer timer; private MyBroadCastRecever recever; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mian_activity); //实例化媒体播放器 mediaPlayer=MediaPlayer.create(this, R.raw.sc); //实例化通知管理器 notificationManager=(NotificationManager) this.getSystemService(NOTIFICATION_SERVICE); timer=new Timer(); imageView=(ImageView) this.findViewById(R.id.imageView); imageView.setOnClickListener(onClickListener); //注冊接收通知栏发送的广播事件 IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction(PAUSEMUSIC_INTENT); intentFilter.addAction(PLAYMUSIC_INTENT); recever=new MyBroadCastRecever(); this.registerReceiver(recever, intentFilter); } OnClickListener onClickListener=new OnClickListener() { @Override public void onClick(View v) { if (!isPlaying) {//没有播放音乐 //開始播放音乐 playMusic(); //更改图片背景 imageView.setImageResource(R.drawable.pause_over); //更改标志 isPlaying=true; }else {//正在播放音乐 //暂停播放音乐 pauseMusic(); //更改图片背景 imageView.setImageResource(R.drawable.play_over); //更改标志 isPlaying=false; } //发送通知栏 activitySendNotification(); } }; /** * 播放音乐 */ protected void playMusic() { if (mediaPlayer==null) { mediaPlayer=MediaPlayer.create(MainActivity.this, R.raw.sc); } if (timer==null) { timer=new Timer(); } //开启计时器任务,每一个一秒 更新抽屉通知音乐播放进度 timer.schedule(new MyTimerTask(), 0, 1000); //播放音乐 mediaPlayer.start(); } //时间任务,更新抽屉通知,播放进度(注意:每次调用必须又一次new) private class MyTimerTask extends TimerTask{ @Override public void run() { //活动端发送通知 activitySendNotification(); } } /** * 发送通知 */ protected void activitySendNotification() { //通知构建器 NotificationCompat.Builder builder=new NotificationCompat.Builder(this); //设置小图标 builder.setSmallIcon(R.drawable.favorite); //载入自己定义远程布局 RemoteViews remoteView=(RemoteViews) new RemoteViews(this.getPackageName(), R.layout.my_notification); //设置不能够拉动取消抽屉通知 builder.setOngoing(true); //设置标题 remoteView.setTextViewText(R.id.tv_title, "Sweet Child O' Mine"); //当前播放时间(注意:当进入界面播放音乐时退出界面,不是暂停时退出界面,那么就有可能在程序运行 //onDestroy()方法时将mediaPlayer释放并置空了,而此段代码是在子线程中的,与主线程不同步退出, //那么就导致mediaPlayer为空,从而报错) if (mediaPlayer==null) { return; } Date currentDate=new Date(mediaPlayer.getCurrentPosition()); //总时长 Date totalDate=new Date(mediaPlayer.getDuration()); SimpleDateFormat simpleDateFormat=new SimpleDateFormat("mm:ss"); //设置当前播放时间进度 remoteView.setTextViewText(R.id.tv_nowTime, simpleDateFormat.format(currentDate)); //设置歌曲总时长 remoteView.setTextViewText(R.id.tv_totallTime, simpleDateFormat.format(totalDate)); Log.i("liujun", "是否正在播放音乐:--"+isPlaying); if (isPlaying) {//正在播放音乐 //显示能够暂停图片 remoteView.setImageViewResource(R.id.image_control, R.drawable.pause_over); }else { //显示能够播放图片 remoteView.setImageViewResource(R.id.image_control, R.drawable.play_over); } //通知栏,交互互动 notificationToActivity(remoteView,isPlaying); //载入视图布局 builder.setContent(remoteView); //创建通知 Notification notification=builder.build(); //发送通知 notificationManager.notify(NOTIFICATION_ID, notification); } /** * 通知栏交互活动 * @param isPlaying */ private void notificationToActivity(RemoteViews remoteView,boolean isPlaying) { Intent intent=new Intent(); if (isPlaying) {//正在播放音乐 //试图暂停播放音乐 intent.setAction(PAUSEMUSIC_INTENT); //更改图片 remoteView.setImageViewResource(R.id.image_control, R.drawable.pause_over); /* //更新标志 isPlaying=false;*/ }else {//没有播放音乐 //试图播放音乐 intent.setAction(PLAYMUSIC_INTENT); //更改图片 remoteView.setImageViewResource(R.id.image_control, R.drawable.play_over); /*//更新标志 isPlaying=true;*/ } //发送广播,更新Activity PendingIntent pendingIntent=PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); remoteView.setOnClickPendingIntent(R.id.image_control, pendingIntent); } //广播接收器(接收通知发送的广播事件) private class MyBroadCastRecever extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if (intent.getAction()==PLAYMUSIC_INTENT) {//通知端播放音乐 //播放音乐 playMusic(); //是否播放正在播放音乐标志 isPlaying=true; //更改图片标志 imageView.setImageResource(R.drawable.pause_over); }else if(intent.getAction()==PAUSEMUSIC_INTENT){//通知端暂停音乐 //暂停音乐 pauseMusic(); //是否播放正在播放音乐标志 isPlaying=false; //更改图片标志 imageView.setImageResource(R.drawable.play_over); } //上面更新活动的信息,这时又要发送通知 activitySendNotification(); } } /** * 暂停播放音乐 */ protected void pauseMusic() { if (mediaPlayer!=null&&mediaPlayer.isPlaying()) { mediaPlayer.pause(); } //暂停发送通知 if (timer!=null) { timer.cancel(); timer=null; } } @Override protected void onDestroy() { super.onDestroy(); this.unregisterReceiver(recever); //释放资源 if (mediaPlayer!=null) { mediaPlayer.release(); mediaPlayer=null; } //是否通知栏 notificationManager.cancel(NOTIFICATION_ID); } }