Android 音乐播放器的开发教程(十)通知栏Notification的使用 ----- 小达
来源:互联网 发布:类似itools的软件 编辑:程序博客网 时间:2024/06/04 23:18
通知栏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
0 0
- Android 音乐播放器的开发教程(十)通知栏Notification的使用 ----- 小达
- Android开发:用通知栏(Notification Bar)控制音乐的后台播放
- Android 音乐播放器的开发教程(十一)SQLite的使用及最近播放的实现 ----- 小达
- Android 音乐播放器的开发教程(六)service的运用及音乐列表点击播放 ----- 小达
- Android 音乐播放器的开发教程(三) 小卷毛播放器的主界面开发 ---- 小达
- Android 音乐播放器的开发教程(九) 歌词的显示----- 小达
- Android 音乐播放器的开发教程(一) ----- 小达
- Android 音乐播放器的开发教程(二)反编译apk ----- 小达
- 基于android的网络音乐播放器-通知栏控制(RemoteViews)(十)
- Android 音乐播放器的开发教程(五)本地音乐的获取及显示 ----- 小达
- Android 音乐播放器的通知栏
- Android 音乐播放器的开发教程(十二)SQLite的使用及我的最爱歌曲的实现 ----- 小达
- Android 音乐播放器的开发教程(四)Activity和Fragment的通信以及Fragment的切换 ----- 小达
- Android 音乐播放器的开发教程(八)歌曲的切换和进度条的拖动 ----- 小达
- Android 音乐播放器的开发教程(七)运用Broadcast实现service与activity的通信 ----- 小达
- 【Android开发】音乐播放器的小例子
- 音乐播放器通知栏切歌(Notification+BroadcastReceiver)
- Android仿虾米音乐播放器之通知栏notification解析
- 多态实例
- 不能在主文件中用include来包含子文件
- Boost练习4——内存管理之内存池
- cron表达式详解
- RGB/HSV/YUV颜色空间模型总结
- Android 音乐播放器的开发教程(十)通知栏Notification的使用 ----- 小达
- 堆排序练习(手痒)
- 再见2014,你好2015
- 第五章思维导图
- I2C上拉电阻取值问题 fine
- java线程的典例
- VS中“未找到与约束”
- Find Minimum in Rotated Sorted Array
- Android APK反编译详解