android 音乐播放器

    本章以音乐播放器为载体,介绍android开发中,通知模式Notification应用。主要涉及知识点Notification,seekbar,service。

1.功能需求

  • 完善音乐播放器
  • 有播放列表和播放服务,播放服务放在另外一个进程,分别用Messenger通信。播放显示类似网易云音乐的Notification。

2.软件实现

                      图1

    编写一个手指移动监听事件,手指向右滑动,可实现切歌功能。

                      图2

    编写一个手指移动监听事件,手指向左滑动,可实现切歌功能。

                     图3

    播放器界面下方的左右,暂停按钮也可切换歌曲。

                     图4

    播放器通知模块仿照网易的播放器,可操作歌曲和展示。

3.相关知识

(1)SeekBar

    Android中组件有很多种,其中SeekBar就是其中经常见到的组件之一。SeekBar是滑动条组件,在音视频的播放器的下面经常看到。

该组件的属性

  • android:max              // 设置范围最大值
  • android:progress        //设置当前进度值
  • android:secondaryProgress             // 设置当前次进度值
  • android:progressDrawable               //设置进度条的图片
  • android:thumb                                //设置进度条的滑块的图片

常用的方法

  • getMax()         // 获取最大范围值
  • getProgress()        // 获取当前进度值
  • setMax(int)           //设置范围最大值
  • setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener l)。监听器
  • SeekBar.OnSeekBarChangeListener中可以监听三种事件:数值的改变(onProgressChanged)、开始拖动(onStartTrackingTouch)、停止拖动(onStopTrackingTouch)。

(2)Notification

Notification简介

    Notification,俗称通知,是一种具有全局效果的通知,它展示在屏幕的顶端,首先会表现为一个图标的形式,当用户向下滑动的时候,展示出通知具体的内容。
  注意:因为一些Android版本的兼容性问题,对于Notification而言,Android3.0是一个分水岭,在其之前构建 Notification推荐使用Notification.Builder构建,而在Android3.0之后,一般推荐使用 NotificationCompat.Builder构建。

    通知一般通过NotificationManager服务来发送一个Notification对象来完成,NotificationManager是一个重要的系统级服务,该对象位于应用程序的框架层中,应用程序可以通过它像系统发送全局的通知。这个时候需要创建一个Notification对象,用于承载通知的内容。但是一般在实际使用过程中,一般不会直接构建Notification对象,而是使用它的一个内部类 NotificationCompat.Builder来实例化一个对象(Android3.0之下使用Notification.Builder),并 设置通知的各种属性,最后通过NotificationCompat.Builder.build()方法得到一个Notification对象。当获得 这个对象之后,可以使用NotificationManager.notify()方法发送通知。   

    NotificationManager类是一个通知管理器类,这个对象是由系统维护的服务,是以单例模式获得,所以一般并不直接实例化这个对象。在 Activity中,可以使用Activity.getSystemService(String)方法获取NotificationManager对 象,Activity.getSystemService(String)方法可以通过Android系统级服务的句柄,返回对应的对象。在这里需要返回 NotificationManager,所以直接传递Context.NOTIFICATION_SERVICE即可。

    在使用NotificationManager.notify()发送通知的时候,需要传递一个标识符,用于唯一标识这个通知。对于有些场景,并不是无限 的添加新的通知,有时候需要更新原有通知的信息,这个时候可以重写构建Notification,而使用与之前通知相同标识符来发送通知,这个时候旧的通 知就被被新的通知所取代,起到更新通知的效果。
  对于一个通知,当展示在状态栏之后,但是使用过后,如何取消呢?Android为我们提供两种方式移除通知,一种是Notification自己维护,使用setAutoCancel()方法设置是否维护,传递一个boolean类型的数据。另外一种方式使用NotificationManager 通知管理器对象来维护,它通过notify()发送通知的时候,指定的通知标识Id来操作通知,可以使用cancel(int)来移除一个指定的通知,也 可以使用cancelAll()移除所有的通知。

 Notification有两种视觉风格,一种是标准视图(Normal view)、一种是大视图(Big view)。标准视图在Android中各版本是通用的,但是对于大视图而言,仅支持Android4.1+的版本。
 从官方文档了解到,一个标准视图显示的大小要保持在64dp高,宽度为屏幕标准。标准视图的通知主体内容有一下几个:   

  • 标题   Title/Name
  • 大图标  Icon/Photo
  • 内容文字  
  • 内容信息   MESSAGE
  • 小图标 Secondary Icon
  • 通知的时间 Timestamp,默认为系统发出通知的时间,也可通过setWhen()来设置

 而对于大视图(Big View)而言,它的细节区域只能显示256dp高度的内容,并且只对Android4.1+之后的设备才支持,它比标准视图不一样的地方,均需要使用setStyle()方法设定,它大致的效果如下:
 setStyle()传递一个NotificationCompat.Style对象,它是一个抽象类,Android为我们提供了三个实现类,用于显示不同的场景。分别是:

  • NotificationCompat.BigPictureStyle, 在细节部分显示一个256dp高度的位图。
  • NotificationCompat.BigTextStyle,在细节部分显示一个大的文本块。
  • NotificationCompat.InboxStyle,在细节部分显示一段行文本。
  • 如果仅仅显示一个图片,使用BigPictureStyle是最方便的;
  • 如果需要显示一个富文本信息,则可以使用BigTextStyle;
  • 如果仅仅 用于显示一个文本的信息,那么使用InboxStyle即可。

Notification丰富的提示方式:

    声音提醒

  • 使用默认声音  notification.defaults |= Notification.DEFAULT_SOUND;
  • 使用自定义声音  notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");
  • 注:如果定义了默认声音,那么自定义声音将被覆盖

    振动提醒

  • 使用默认振动  notification.defaults |= Notification.DEFAULT_VIBRATE;
  • 使用自定义振动  long[] vibrate = {0,100,200,300}; notification.vibrate = vibrate;
  • 注:如果定义了默认振动,那么自定义振动将被覆盖

    灯光闪烁提醒

  • 使用默认闪烁  notification.defaults |= Notification.DEFAULT_LIGHTS;
  • 使用自定义闪烁  notification.ledARGB = 0xff00ff00; // LED灯的颜色,绿灯  notification.ledOnMS = 300; // LED灯显示的毫秒数,300毫秒  notification.ledOffMS = 1000; // LED灯关闭的毫秒数,1000毫秒  notification.flags |= Notification.FLAG_SHOW_LIGHTS; // 必须加上这个标志

    可以通过 Notification 的相关字段或标志(flags)为提醒设置更多的特性。

  • FLAG_AUTO_CANCEL 标志:当提醒被用户点击之后会自动被取消(cancel);
  • FLAG_INSISTENT 标志:在用户响应之前会一直重复提醒音;
  • FLAG_ONGOING_EVENT 标志:Add this to the flags field to group the notification under the "Ongoing" title in the Notifications window.
  • FLAG_NO_CLEAR 标志:当在提醒栏中点击“清除提醒”按钮时,该提醒将不会被清除;
  • number 字段:This value indicates the current number of events represented by the notification.The appropriate number is overlaid on top of the status bar icon. If you intend to use this field, then you must start with "1" when the Notification is first created. (If you change the value from zero to anything greater during an update, the number is not shown.)
  • iconLevel 字段:This value indicates the current level of a LevelListDrawable that is used for the notification icon. You can animate the icon in the status bar by changing this value to correlate with the drawable's defined in a LevelListDrawable.
  • contentView 字段:To define your own layout for the expanded message, instantiate a RemoteViews object and pass it to the contentView field of your Notification. Pass the PendingIntent to the contentIntent field.

Notification自定义样式

     自定义样式,就是让Notification在通知栏显示成自定义的xml布局应当注意的是,Notification的自定义样式,只支持以下可视组件:FrameLayout, LinearLayout, RelativeLayout,TextView, Button, AnalogClock, ImageView, ImageButton, Chronometer, ProgressBar.

4.项目代码

自定义音乐播放器的通知栏xml界面源码如下:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="horizontal" >
 6     <ImageView
 7         android:id="@+id/songer_pic"
 8         android:layout_width="80dp"
 9         android:layout_height="70dp"
10         android:scaleType="fitXY"
11         android:src="@mipmap/picture_1" />
12     <LinearLayout
13         android:layout_width="fill_parent"
14         android:layout_height="wrap_content"
15         android:gravity="center_vertical"
16         android:orientation="vertical" >
17         <TextView
18             android:id="@+id/song_name"
19             android:layout_width="wrap_content"
20             android:layout_height="wrap_content"
21             android:textColor="@color/white"
22             android:textSize="18dp"
23             android:text="播放音乐"
24             android:layout_marginTop="5dp"
25             android:layout_marginLeft="15dp"
26            />
27     <LinearLayout
28         android:layout_width="fill_parent"
29         android:layout_height="48dp"
30         android:gravity="center_vertical"
31         android:orientation="horizontal" >
32         <ImageView
33             android:id="@+id/previous_music"
34             android:layout_width="0dp"
35             android:layout_height="48dp"
36             android:layout_weight="1"
37             android:src="@mipmap/lock_btn_prev" />
38         <ImageView
39             android:id="@+id/paly_pause_music"
40             android:layout_width="0dp"
41             android:layout_height="48dp"
42             android:layout_weight="1"
43             android:src="@mipmap/lock_btn_play" />
44 
45         <ImageView
46             android:id="@+id/next_music"
47             android:layout_width="0dp"
48             android:layout_height="48dp"
49             android:layout_weight="1"
50             android:src="@mipmap/lock_btn_next" />
51     </LinearLayout>
52     </LinearLayout>
53 </LinearLayout>

 

自定义音乐播放器通知Notification源代码:

 1    public void showButtonNotify(int songid){
 2         NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
 3         RemoteViews mRemoteViews = new RemoteViews(getPackageName(), R.layout.music_notification);
 4         //设置音乐播放图片
 5         mRemoteViews.setImageViewResource(R.id.songer_pic, MusicUtil.SetMusicBackgroupMess(songid));
 6         //设置歌曲名称
 7         mRemoteViews.setTextViewText(R.id.song_name, MusicUtil.SetMusicName(songid));
 8         //设置播放,暂停按钮图片
 9           if(!mPlayState)
10               mRemoteViews.setImageViewResource(R.id.paly_pause_music, R.mipmap.lock_btn_play);
11          else
12               mRemoteViews.setImageViewResource(R.id.paly_pause_music, R.mipmap.lock_btn_pause);
13         //点击的事件处理
14         Intent buttonIntent = new Intent(MusicService.USR_ACTION);
15             /* 上一首按钮 */
16         buttonIntent.putExtra(KEY_USR_ACTION, MusicService.ACTION_PRE);
17         //这里加了广播,所及INTENT的必须用getBroadcast方法
18         PendingIntent intent_prev = PendingIntent.getBroadcast(this, 1, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
19         mRemoteViews.setOnClickPendingIntent(R.id.previous_music, intent_prev);
20             /* 播放/暂停  按钮 */
21         buttonIntent.putExtra(KEY_USR_ACTION, MusicService.ACTION_PLAY_PAUSE);
22         PendingIntent intent_paly = PendingIntent.getBroadcast(this, 2, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
23         mRemoteViews.setOnClickPendingIntent(R.id.paly_pause_music, intent_paly);
24             /* 下一首 按钮  */
25         buttonIntent.putExtra(KEY_USR_ACTION, MusicService.ACTION_NEXT);
26         PendingIntent intent_next = PendingIntent.getBroadcast(this, 3, buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
27         mRemoteViews.setOnClickPendingIntent(R.id.next_music, intent_next);
28         /* 点击页面其他部分事件 */
29         Intent notificationIntent1 = new Intent(this, this.getClass());
30         notificationIntent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
31         PendingIntent contentIntent1 = PendingIntent.getActivity(this, 0, notificationIntent1, 0);
32 //        NotificationCompat.BigTextStyle inboxStyle = new NotificationCompat.BigTextStyle();
33 //        inboxStyle.setBigContentTitle("大视图内容:");
34         mBuilder.setContent(mRemoteViews)
35                 .setContentIntent(contentIntent1)
36                 .setWhen(System.currentTimeMillis())// 通知产生的时间,会在通知信息里显示
37                 //.setStyle(inboxStyle)//设置风格
38                 .setTicker("正在播放")
39                 .setPriority(Notification.PRIORITY_DEFAULT)// 设置该通知优先级
40                 .setOngoing(true)
41                 .setSmallIcon(R.mipmap.ic_launcher);
42         Notification notify = mBuilder.build();
43         notify.flags = Notification.FLAG_ONGOING_EVENT;
44         NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
45         mNotificationManager.notify(0, notify);
46     }
posted @ 2016-04-29 18:53  无涯Ⅱ  阅读(746)  评论(0编辑  收藏  举报