一个迷你音频播放器项目

研究生入学后碰上的第一个老师布置的Android小项目,也是借此机会复习一下本科时接触的安卓开发,主要包括两个部分:


一、音乐播放器

利用安卓提供的MediaPlayer媒体播放类实现简单的开始、暂停、以及停止指定音乐文件的播放功能,要求暂停后点击开始能够继续播放,停止后点击开始能够从头开始:

1) 基础的界面布局和控件(开始、暂停、停止三个按钮)设计,以及所有按钮相应的事件监听代码的实现:

主Activity代码:

MediaPlayerActivity.java:

package android.mediaplayer;

import java.io.IOException;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;


public class MediaPlayerActivity extends Activity {
    /** Called when the activity is first created. */
	MediaPlayer mMediaPlayer;
	TextView mTextView;
	ImageButton mPlay;
	ImageButton mPause;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
		
        //创建MediaPlayer对象,音乐文件位置:/res/raw/ifeveryonecared.mp3
        mMediaPlayer = MediaPlayer.create(MediaPlayerActivity.this,  R.raw.ifeveryonecared);
        mTextView = (TextView)findViewById(R.id.activeText);
        mPlay = (ImageButton)findViewById(R.id.PlayBtn);
        mPause = (ImageButton)findViewById(R.id.PauseBtn);
        ImageButton mStop = (ImageButton)findViewById(R.id.StopBtn);
        
        mPlay.setOnClickListener(new playListener());
        
        mPause.setOnClickListener(new pauseListener());
        
        mStop.setOnClickListener(new stopListener());
    }
    
    
    class playListener implements OnClickListener{
    	
    	public void onClick(View v)
    	{
    		try
    		{
    				//设置音乐循环播放
    				mMediaPlayer.setLooping(true); 				
    				try
    				{
    					//准备开始
    					mMediaPlayer.prepare();
    				}
    				catch(IllegalStateException e)
    				{
    					e.printStackTrace();
    				}
    				catch(IOException e)
    				{
    					e.printStackTrace();
    				}
    				
    				mMediaPlayer.start();
    				mTextView.setText("正在播放音乐!");
    				mPause.setVisibility(View.VISIBLE);
            		mPlay.setVisibility(View.INVISIBLE);
    			}
    		
    		catch (IllegalStateException e)
    		{
    			e.printStackTrace();
    		}
    		mMediaPlayer.setOnCompletionListener(new OnCompletionListener()
    		{
    			public void onCompletion(MediaPlayer arg0)
    			{
    				//释放资源
    				mMediaPlayer.release();
    			}
    		});
    	}
}
    
    class pauseListener implements OnClickListener
    {
        	public void onClick(View v)
        	{
        		try
        		{
        				try
        				{
        					mMediaPlayer.prepare();
        				}
        				catch(IllegalStateException e)
        				{
        					e.printStackTrace();
        				}
        				catch(IOException e)
        				{
        					e.printStackTrace();
        				}
        				
        				mMediaPlayer.pause();;
        				mTextView.setText("已暂停,点击播放按钮可继续!");
        				mPause.setVisibility(View.INVISIBLE);
                		mPlay.setVisibility(View.VISIBLE);
        			}
        		
        		catch (IllegalStateException e)
        		{
        			e.printStackTrace();
        		}
        		mMediaPlayer.setOnCompletionListener(new OnCompletionListener()
        		{
        			public void onCompletion(MediaPlayer arg0)
        			{
        				mMediaPlayer.release();
        			}
        		});
        	}
        	
    }
    
    class stopListener implements OnClickListener
    {
        	public void onClick(View v)
        	{
        		try
        		{
        				mMediaPlayer.setLooping(true);
        				try
        				{
        					mMediaPlayer.prepare();
        				}
        				catch(IllegalStateException e)
        				{
        					e.printStackTrace();
        				}
        				catch(IOException e)
        				{
        					e.printStackTrace();
        				}
        				
        				mMediaPlayer.stop();
        				mTextView.setText("已停止,点击播放按钮重新播放!");
        				mPause.setVisibility(View.INVISIBLE);
                		mPlay.setVisibility(View.VISIBLE);
        			}
        		
        		catch (IllegalStateException e)
        		{
        			e.printStackTrace();
        		}
        		
        		mMediaPlayer.setOnCompletionListener(new OnCompletionListener()
        		{
        			public void onCompletion(MediaPlayer arg0)
        			{
        				mMediaPlayer.release();
        			}
        		});
        	}
    }
}

布局文件main.xml:




    

        
    





        

    


        

            

            
        


        

    


这里由于考虑到实际需求,在音乐播放时会隐藏开始按钮,音乐暂停或停止后会重新显示开始按钮。


2) 开始运行(Android版本2.3.3)后,基础的播放、暂停、停止、暂停后播放功能均正常,不过当按下停止按钮后,再点击开始按钮没有声音,音乐不会从头开始播放。在网上查找关于MediaPlayer的start()、pause()、和stop()的用法后,发现若要实现重新播放,应在当前播放音乐暂停后,将播放进度重新设置到文件开头,即将mMediaPlayer.stop()更改为:

mMediaPlayer.pause();
mMediaPlayer.seekTo(0);
重新运行项目后,停止后重新播放功能正常运行。


二、视频播放器

这个相对来说更简单,利用MediaPlayer类和SurfaceView类(Android提供的媒体播放绘图窗口,不占用主UI线程)配合的方式实现:


1) 

主Activity代码:

VideoPlayerActivity:

package android.video;

import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

public class VideoPlayerActivity extends Activity{
    /** Called when the activity is first created. */
	MediaPlayer mMediaPlayer = new MediaPlayer();
	SurfaceView sv;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        sv = (SurfaceView)findViewById(R.id.surface);
        SurfaceHolder sh = sv.getHolder();
        //为surface指定PUSH类型的缓冲区,在视频播放和相机预览中通常使用PUSH_BUFFERS
        sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        sh.addCallback(new Callback()
        /* 为正常使用SurfaceView,必须实现以下三个方法(SurfaceView的生命周期)*/
        {          
            public void surfaceDestroyed(SurfaceHolder holder) {  
            	System.out.println("Destroyed调用调试...");
            }  
          
            public void surfaceCreated(SurfaceHolder holder) {  
                    try {  
                        //开始播放  
                        play();  
                        System.out.println("准备开始...");
                        mMediaPlayer.seekTo(0);
                    } catch (Exception e) {  
                        // TODO: handle exception  
                    }  
            }             
            public void surfaceChanged(SurfaceHolder holder, int format, int width,  
                    int height) {  
            			System.out.println("Change调用调试...");
            }  
        }); 
        
    }
    

    private void play() {  
        try {  
            mMediaPlayer.reset();  
            mMediaPlayer  
            .setAudioStreamType(AudioManager.STREAM_MUSIC);  
            //设置需要播放的视频  
            mMediaPlayer.setDataSource("/mnt/sdcard/TestVideo.3gp");  
            //把视频画面输出到SurfaceView  
            mMediaPlayer.setDisplay(sv.getHolder());  
            mMediaPlayer.prepare();  
            //播放  
            mMediaPlayer.start();          
        } catch (Exception e) {  
            // TODO: handle exception  
        }  
    }  
}

为便于调试,同时也想稍微探索下SurfaceView运行过程中发生了什么,这里在其surfaceCreated()、surfaceChanged()、surfaceDestroyed()三个方法中加入了相应的输出语句。


布局文件main.xml:





        
    





    


    


2) 不出所料,视频可以正常播放。另外,查看了一下LogCat里的日志记录:

前两条输出语句是在视频播放开始时输出的,最后一条则是在退出app时输出。(你有没有发现了什么?)


最后值得一提的是,如果选择的视频文件的编码手机不支持,是会报 error (1, -2147483648)这样一个错误的,这个也好解决,去重新下一个手机视频或者格式转换一下即可。

你可能感兴趣的:(项目)