研究生入学后碰上的第一个老师布置的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
}
}
}
布局文件main.xml:
前两条输出语句是在视频播放开始时输出的,最后一条则是在退出app时输出。(你有没有发现了什么?)
最后值得一提的是,如果选择的视频文件的编码手机不支持,是会报 error (1, -2147483648)这样一个错误的,这个也好解决,去重新下一个手机视频或者格式转换一下即可。