Android构建音频播放器教程(一)

  

 下面这篇文章我在国外的网站上看到的,感觉质量很不错,所以就花了一些时间来翻译一下,并且里面也加入了我自己的开发经验,希望这篇文章能够为广大Android开发者提供一个帮助。

  在本教程中,我将讨论构建一个简单的播放器,有基本的控件,比如播放、暂停、前进、后退,下一首,前一首,播放列表和进度条。这款应用基本上会读所有的音频文件(mp3)从sdcard,然后播放选中歌曲。对于本教程我引用MediaPlayer类来实现这个App.

  

Android MediaPlayer Class

 Android SDK提供了MediaPlayer这个类在Android里构建媒体服务例如音频,视频的播放等等。在本教程中,我使用下面这个类的功能控制音频播放器。
MediaPlayer mp = new MediaPlayer();
 
// Set data source -
setDataSource( "/sdcard/path_to_song" );
 
// Play audio
mp.start();
 
// Pause audio
mp.pause();
 
// Reset mediaplayer
mp.reset();
 
// Get song length duration - in milliseconds
mp.getDuration();
 
// Get current duration - in milliseconds
mp.getCurrentDuration();
 
// Move song to particular second - used for Forward or Backward
mp.seekTo(positon); // position in milliseconds
 
// Check if song is playing or not
mp.isPlaying(); // returns true or false

1. Designing the Audio Player Layout


  设计你的音频播放器可以使用一些平面设计软件例如photoshop之类,当然这个是专业的要求,因为我们要做的更好。我用photoshop来设计这款应用程序的布局。如果你不想自己设计可以从互联网下载图片使用,下面是一张截图,音频播放器,我们将在本教程中构建。

                                       

2. 准备所需的 Icons and Images

  一旦你完成了你的应用程序的布局设计,为音频播放器应用程序准备所需的图标和背景图像,准备不同状态下的图标,例如默认,聚焦,按下等等。然后把它们放在drawable文件夹下。
                           
                        

3. 为不同状态的ICON写布局 (默认/聚焦/按下)

  在保存所有不同状态的图标之后,我们需要为每一个icon写布局,下面是一个play button的布局,在drawable文件夹下创建并保存。
btn_play.xml
< selector xmlns:android = "http://schemas.android.com/apk/res/android" >
     < item android:drawable = "@drawable/img_btn_play_pressed"
         android:state_focused = "true"
         android:state_pressed = "true" />
     < item android:drawable = "@drawable/img_btn_play_pressed"
         android:state_focused = "false"
         android:state_pressed = "true" />
     < item android:drawable = "@drawable/img_btn_play_pressed"
             android:state_focused = "true" />
     < item android:drawable = "@drawable/img_btn_play"
         android:state_focused = "false"
         android:state_pressed = "false" />
</ selector>
注意: 其他的icon根据这个例子来写(如btn_pause.xmlbtn_next.xml etc,.)

4. 为SeekBar写布局设计

  在本教程中,我使用定制的SeekBar显示歌曲的进展,您可以设计默认风格的SeekBar通过使用xml样式。在drawable文件夹下建立xml文件夹并创建
seekbar_progress_bg.xml 这个是改变SeekBar的背景样式(不使用默认的)

<?xmlversion="1.0"encoding="utf-8"?>
 <layer-listxmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <clip>
        <bitmapxmlns:android="http://schemas.android.com/apk/res/android"
            android:src="@drawable/img_seekbar_progress_blue"
            android:tileMode="repeat"
            android:antialias="true"
            android:dither="false"
            android:filter="false"
            android:gravity="left"
        />
        </clip>
    </item>
</layer-list>

seekbar_progress.xml  这个是改变 SeekBar的进度条样式
<? xml version = "1.0" encoding = "utf-8" ?>
< layer-list xmlns:android = "http://schemas.android.com/apk/res/android" >
     < item android:id = "@android:id/background"
         android:drawable = "@drawable/img_seekbar_bg"
         android:dither = "true" >
     </ item >
     < item android:id = "@android:id/secondaryProgress" >
         < clip >
             < shape >
                 < gradient
                     android:startColor = "#80028ac8"
                     android:centerColor = "#80127fb1"
                     android:centerY = "0.75"
                     android:endColor = "#a004638f"
                     android:angle = "270"
                 />
             </ shape >
         </ clip >
     </ item >
     < item
         android:id = "@android:id/progress"
         android:drawable = "@drawable/seekbar_progress_bg"
     />
</ layer-list >
<? xml version = "1.0" encoding = "utf-8" ?>
< layer-list xmlns:android = "http://schemas.android.com/apk/res/android" >
     < item android:id = "@android:id/background"
         android:drawable = "@drawable/img_seekbar_bg"
         android:dither = "true" >
     </ item >
     < item android:id = "@android:id/secondaryProgress" >
         < clip >
             < shape >
                 < gradient
                     android:startColor = "#80028ac8"
                     android:centerColor = "#80127fb1"
                     android:centerY = "0.75"
                     android:endColor = "#a004638f"
                     android:angle = "270"
                 />
             </ shape >
         </ clip >
     </ item >
     < item
         android:id = "@android:id/progress"
         android:drawable = "@drawable/seekbar_progress_bg"
     />
</ layer-list >

  如下是 SeekBar的xml布局,可以看到在他的属性里面调用了上面两个xml文件,这样就实现了自定义样式。
< SeekBar
             android:id = "@+id/songProgressBar"
              android:layout_width = "fill_parent"
              android:layout_height = "wrap_content"
              android:layout_marginRight = "20dp"
              android:layout_marginLeft = "20dp"
              android:layout_marginBottom = "20dp"
              android:layout_above = "@id/player_footer_bg"
              android:thumb = "@drawable/seek_handler"
              android:progressDrawable = "@drawable/seekbar_progress"
              android:paddingLeft = "6dp"
              android:paddingRight = "6dp" />

5. 为Player写XML布局

  到目前为止,我们为所有的图标,seekbar创建了单独的xml布局,现在我们需要将所有东西组合起来都变成单独布局。在layout创建一个新文件player.xml 
player.xml
<? xml version = "1.0" encoding = "utf-8" ?>
< RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
     android:layout_width = "match_parent"
     android:layout_height = "match_parent"
     android:background = "@color/player_background" >
 
     <!-- Player Header -->
     < LinearLayout
         android:id = "@+id/player_header_bg"
         android:layout_width = "fill_parent"
         android:layout_height = "60dip"
         android:background = "@layout/bg_player_header"
         android:layout_alignParentTop = "true"
         android:paddingLeft = "5dp"
         android:paddingRight = "5dp" >
 
         <!-- Song Title -->
         < TextView
             android:id = "@+id/songTitle"
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:layout_weight = "1"
             android:textColor = "#04b3d2"
             android:textSize = "16dp"
             android:paddingLeft = "10dp"
             android:textStyle = "bold"
             android:text = "The Good, The Bad And The Ugly"
             android:layout_marginTop = "10dp" />
 
         <!-- Playlist button -->
         < ImageButton
             android:id = "@+id/btnPlaylist"
             android:layout_width = "wrap_content"
             android:layout_height = "fill_parent"
             android:src = "@drawable/btn_playlist"
             android:background = "@null" />
     </ LinearLayout >
 
     <!-- Song Thumbnail Image -->
     < LinearLayout
         android:id = "@+id/songThumbnail"
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:paddingTop = "10dp"
         android:paddingBottom = "10dp"
         android:gravity = "center"
         android:layout_below = "@id/player_header_bg" >
         < ImageView android:layout_width = "wrap_content"
         android:layout_height = "wrap_content"
         android:src = "@drawable/adele" />
     </ LinearLayout >
 
     <!-- Player Footer -->
     < LinearLayout
         android:id = "@+id/player_footer_bg"
         android:layout_width = "fill_parent"
         android:layout_height = "100dp"
         android:layout_alignParentBottom = "true"
         android:background = "@layout/bg_player_footer"
         android:gravity = "center" >
 
         <!-- Player Buttons -->
         < LinearLayout
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:orientation = "horizontal"
             android:gravity = "center_vertical"
             android:background = "@layout/rounded_corner"
             android:paddingLeft = "10dp"
             android:paddingRight = "10dp" >
             <!-- Previous Button -->
             < ImageButton
                 android:id = "@+id/btnPrevious"
                 android:src = "@drawable/btn_previous"
                 android:layout_width = "wrap_content"
                 android:layout_height = "wrap_content"
                 android:background = "@null" />
             <!-- Backward Button -->
             < ImageButton
                 android:id = "@+id/btnBackward"
                 android:src = "@drawable/btn_backward"
                 android:layout_width = "wrap_content"
                 android:layout_height = "wrap_content"
                 android:background = "@null" />
             <!-- Play Button -->
             < ImageButton
                 android:id = "@+id/btnPlay"
                 android:src = "@drawable/btn_play"
                 android:layout_width = "wrap_content"
                 android:layout_height = "wrap_content"
                 android:background = "@null" />
             <!-- Forward Button -->
             < ImageButton
                 android:id = "@+id/btnForward"
                 android:src = "@drawable/btn_forward"
                 android:layout_width = "wrap_content"
                 android:layout_height = "wrap_content"
                 android:background = "@null" />
             <!-- Next Button -->
             < ImageButton
                 android:id = "@+id/btnNext"
                 android:src = "@drawable/btn_next"
                 android:layout_width = "wrap_content"
                 android:layout_height = "wrap_content"
                 android:background = "@null" />
         </ LinearLayout >
     </ LinearLayout >
 
     <!-- Progress Bar/Seek bar -->
     < SeekBar
             android:id = "@+id/songProgressBar"
              android:layout_width = "fill_parent"
              android:layout_height = "wrap_content"
              android:layout_marginRight = "20dp"
              android:layout_marginLeft = "20dp"
              android:layout_marginBottom = "20dp"
              android:layout_above = "@id/player_footer_bg"
              android:thumb = "@drawable/seek_handler"
              android:progressDrawable = "@drawable/seekbar_progress"
              android:paddingLeft = "6dp"
              android:paddingRight = "6dp" />
 
     <!-- Timer Display -->
     < LinearLayout
         android:id = "@+id/timerDisplay"
         android:layout_above = "@id/songProgressBar"
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:layout_marginRight = "20dp"
         android:layout_marginLeft = "20dp"
         android:layout_marginBottom = "10dp" >
         <!-- Current Duration Label -->
         < TextView
             android:id = "@+id/songCurrentDurationLabel"
             android:layout_width = "fill_parent"
             android:layout_height = "wrap_content"
             android:layout_weight = "1"
             android:gravity = "left"
             android:textColor = "#eeeeee"
             android:textStyle = "bold" />
         <!-- Total Duration Label -->
         < TextView
             android:id = "@+id/songTotalDurationLabel"
             android:layout_width = "fill_parent"
             android:layout_height = "wrap_content"
             android:layout_weight = "1"
             android:gravity = "right"
             android:textColor = "#04cbde"
             android:textStyle = "bold" />
     </ LinearLayout >
 
     <!-- Repeat / Shuffle buttons -->
     < LinearLayout
         android:layout_width = "fill_parent"
         android:layout_height = "wrap_content"
         android:layout_above = "@id/timerDisplay"
         android:gravity = "center" >
         <!-- Repeat Button -->
         < ImageButton
             android:id = "@+id/btnRepeat"
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:src = "@drawable/btn_repeat"
             android:layout_marginRight = "5dp"
             android:background = "@null" />
 
         <!-- Shuffle Button -->
          < ImageButton
             android:id = "@+id/btnShuffle"
             android:layout_width = "wrap_content"
             android:layout_height = "wrap_content"
             android:src = "@drawable/btn_shuffle"
             android:layout_marginLeft = "5dp"
             android:background = "@null" />
     </ LinearLayout >
</ RelativeLayout >
效果如下:
                            

音频播放实现暂停开始等 }); btnStop.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub musicStop(); } }); player.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { // TODO Auto-generated method stub if(currentPlayMusicNum<musicList.size()){ currentPlayMusicNum+=1; }else{ currentPlayMusicNum=0; } musicStart(currentPlayMusicNum); } }); lvShowMusicList.setOnItemClickListener(new OnItemClickListener() { @SuppressLint("ResourceAsColor") @Override public void onItemClick(AdapterView parent, View view, int position, long id) { if(saveView==view){ saveView.setBackgroundResource(R.color.nocolor); currentPlayMusicNum=0; } else{ if(saveView!=null) saveView.setBackgroundResource(R.color.nocolor); view.setBackgroundResource(R.color.colorblue); saveView=view; currentPlayMusicNum=position; musicStart(currentPlayMusicNum); } //id_this=position; } }); sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { // TODO Auto-generated method stub if(fromUser){ sb.setProgress(progress); //musicPause(); MusicModel music=musicList.get(currentPlayMusicNum); music.setPlayTime(music.getAllTime()*progress/100); //pausePosition=(int) (music.getAllTime()*progress/100); player.seekTo((int) music.getPlayTime()); player.start(); } } }); }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值