音乐播放器、视频播放器、录音、照相、闹钟、铃声设计中的各种方法以及例子总结...

多媒体开发
Open Core是Android多媒体开发框架的核心。所有Android平台的音频、视频的采集以及播放都是通过它来实现的。它也被称为PV(Packet Video).
Open Core是一个多媒体框架,从宏观上看主要包含两大方面的内容:
PVPlayer :提供媒体播放器的功能,完成各种音频(Audio)、视频(Video)流的回放(Playback)功能。
PVAuthor: 提供媒体流记录的功能,完成各种音频、视频流以及静态图像的捕获功能。
第一部分MediaPlayer 类
1.MdiaPlayer类可以用来播放音频,视频和流媒体(所谓流媒体是指采用流式传输的方式在Internet播放的媒体格式。 流媒体又叫流式媒体,它是指商家用一个视频传送服务器
把节目当成数据包发出,传送到网络上。用户通过解压设备对这些数据进行解压后,节目就会像发送前那样显示出来。)。其也包含了Audio和Video的播放功能。
2.当一个MediaPlayer对象被创建或调用了reset()方法后,它处于空闲状态,在调用release()方法后,才会结束状态。
3.MediaPlayer对象在创建时处于空闲状态,如果通过create()方法创建之后便处于准备状态。
4.为了避免MediaPlayer对象处于无效状态而导致错误,我们可以通过注册setOnErrorListener(android.media.MediaPlayer.OnErrorListener)方法实现OnErrorListener.onError()
方法来监控这些错误。如果发生了错误,可以使用reset()方法来恢复错误。
5.任何MediaPlayer对象都必须处于准备状态,然后才能播放。
6.要开始播放MediaPlayer对象必须要成功调用start()方法。可以通过isPlaying()方法来检测当前是否播放。
7.新建的MediaPlayer对象在调用getCurrentPositon(),start(),stop()等方法时不会触发OnErrorListener.onError()事件,但如果MediaPlayer对象调用了reset()方法后,再使用这
些方法则会触发OnErrorListener.onError()事件。
8.当MediaPlayer对象不再被使用时,最好用release()方法来释放,使其处于结束状态,以免出错。当MediaPlayer对象处于结束状态时,便不能再使用。
MediaPlayer类常用方法:
MediaPlayer 构造方法
create创建一个要播放的多媒体
getCurrentPositons 得到当前播放位置
getDuration得到文件时间
getVideoHeight得到视频的高度
getVideoWidth得到视频的宽度
isLooping是否循环播放
isPlaying是否正在播放
pause暂停
prepare准备(同步)
prepareAsync准备(异步)
release释放MediaPlayer对象
reset重置MediaPlayer对象
seekTo指定播放的位置(毫秒)
setAudioStreamType设置流媒体类型
setDataSource设置多媒体数据来源
setDisplay设置用SurfaceHolder来显示多媒体
setLooping设置是否循环播放
setOnBufferUpdateListener设置流媒体缓冲监听
setOnErrorListener设置错误信息监听
setOnVideoSizeChangedListener设置视频尺寸监听
setScreenOnWhilePlaying设置是否使用SurfaceHolder来显示
setVolume设置音量
start开始播放
stop停止播放

Android中通过MediaPlayer来播放音乐步骤:
MediaPlayer mediaplayer = new MediaPlayer();//构建MediaPlayer对象
mediaplayer.setDataSource(“/sdcard/test.mp3”);//设置文件路径
mediaplayer.prepare();//准备
mediaplayer.start();//开始播放

第二部分MediaRecorder类
MediaRecorder类用来进行媒体采样,包括音频和视频。MediaRecorder作为状态机运行,需要设置不同的参数,如格式。
MediaRecorder类的常用方法:
MediaRecorder 构造方法
getMaxAmplitude得到目前为止最大的幅度
prepare准备录用机
release 释放MediaRecorder对象
reset 重置MediaRecorder对象,使其为空闲状态
setAudioEncoder设置音频编码
setAudioSource设置音频源
setCamera设置摄像机
setMaxDuration设置最大期限
setMaxFileSize 设置文件的最大尺寸
setOnErrorListener 错误监听
setOutputFile设置输出文件
setOutputFormat设置输出文件的格式
setPreviewDisplay设置预览
setVideoEncoder设置视频编码
setVideoFrameRate设置视频帧的频率
setVideoSize设置视频的宽度和高度(分辨率)
setVideoSource设置视频源
start开始录制
stop 停止录制

一段简单的录用代码:
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AndrioSource.MTC)
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_MB);
recorder.setOutputFile(PATH_NAME);
recorder.prepare();
recorder.start();
//录用中
recorder.stop();
recorder.reset();
recorder.release();

第三部分音乐播放
法一、播放SD卡上的音乐:
设置路径为/sdcatd/,所有需要先向SD卡中添加一些音频文件。步骤:启动模拟器---DDMS---File Explorer---向左向右分别是拷贝进,拷贝出指定位置,减号是删出选中文件。
public class Activity01 extends ListActivity {
/* 几个操作按钮 */
private ImageButtonmFrontImageButton= null;
private ImageButtonmStopImageButton= null;
private ImageButtonmStartImageButton= null;
private ImageButtonmPauseImageButton= null;
private ImageButtonmNextImageButton= null;
public MediaPlayermMediaPlayer= null;// MediaPlayer对象
private List<String> mMusicList = new ArrayList<String>();//播放列表
private int currentListItme = 0;//当前播放歌曲的索引
private static final String MUSIC_PATH = new String("/sdcard/");//音乐的路径
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
musicList();//更新显示播放列表
mMediaPlayer= new MediaPlayer();//构建MediaPlayer对象

mFrontImageButton = (ImageButton) findViewById(R.id.LastImageButton);
mStopImageButton = (ImageButton) findViewById(R.id.StopImageButton);
mStartImageButton = (ImageButton) findViewById(R.id.StartImageButton);
mPauseImageButton = (ImageButton) findViewById(R.id.PauseImageButton);
mNextImageButton = (ImageButton) findViewById(R.id.NextImageButton);

mStopImageButton.setOnClickListener(new ImageButton.OnClickListener() {//停止按钮
public void onClick(View v){
if (mMediaPlayer.isPlaying()){//是否正在播放
mMediaPlayer.reset();//首先需调用reset()方法,重置MediaPlayer到初始状态,这是必须的一步。
作用:如果正在播放一首歌曲,同时又想去改变这个数据源(即启动下一首歌曲),此方法可将任何正在播放的歌曲。

}
}
});
mStartImageButton.setOnClickListener(new ImageButton.OnClickListener() {//开始按钮
public void onClick(View v){
playMusic(MUSIC_PATH + mMusicList.get(currentListItme));
}
});
mPauseImageButton.setOnClickListener(new ImageButton.OnClickListener(){//暂停
public void onClick(View view){
if (mMediaPlayer.isPlaying()){
mMediaPlayer.pause();//暂停
}else {
mMediaPlayer.start();//开始播放
}
}
});
mNextImageButton.setOnClickListener(new ImageButton.OnClickListener(){//下一首
public void onClick(View arg0){
nextMusic();
}
});
mFrontImageButton.setOnClickListener(new ImageButton.OnClickListener(){//上一首
public void onClick(View arg0){
FrontMusic();
}
});
}
public boolean onKeyDown(int keyCode, KeyEvent event){
if ( keyCode == KeyEvent.KEYCODE_BACK){
mMediaPlayer.stop();
mMediaPlayer.release();
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
protected void onListItemClick(ListView l, View v, int position, long id){ 当我们点击列表时,播放被点击的音乐
currentListItme = position;
playMusic(MUSIC_PATH + mMusicList.get(position));
}
public void musicList(){//播放列表
File home = new File(MUSIC_PATH);//取得指定位置的文件设置显示到播放列表
if (home.listFiles(new MusicFilter()).length > 0){
for (File file : home.listFiles(new MusicFilter())){
mMusicList.add(file.getName());
}
ArrayAdapter<String> musicList = new ArrayAdapter<String>(Activity01.this,R.layout.musicitme, mMusicList);
setListAdapter(musicList);//setListAdapter为装东西用的容器,给listView提供数据的作用
}
}
private void playMusic(String path){
try{
//音乐文件播放步骤如下顺序不能乱
mMediaPlayer.reset();//重置MediaPlayer
mMediaPlayer.setDataSource(path);//设置要播放的文件的路径
mMediaPlayer.prepare();//准备播放
mMediaPlayer.start();//开始播放
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {//此处作用可理解为在播放完一首歌后对事件的监听,如下:设置了播放下一首
public void onCompletion(MediaPlayer arg0){
nextMusic();//播放完成一首之后进行下一首
}
});
}catch (IOException e){}
}
private void nextMusic(){//下一首
if (++currentListItme >= mMusicList.size()){
currentListItme = 0;
}else{
playMusic(MUSIC_PATH + mMusicList.get(currentListItme));
}
}
private void FrontMusic(){//上一首
if (--currentListItme >= 0){
currentListItme = mMusicList.size();
}else{
playMusic(MUSIC_PATH + mMusicList.get(currentListItme));
}
}
}

class MusicFilter implements FilenameFilter{//过滤文件类型 筛选出可以播放的格式
public boolean accept(File dir, String name){
return (name.endsWith(".mp3"));//这里还可以设置其他格式的音乐文件
}
}

musicitem.xml文件
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>

main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<ImageButton
android:id="@+id/LastImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="10px"
android:layout_y="70px"
android:src="@drawable/last"
/>
<ImageButton
android:id="@+id/StopImageButton"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_x="70px"
android:layout_y="70px"
android:src="@drawable/stop"
/>
<ImageButton
android:id="@+id/StartImageButton"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_x="130px"
android:layout_y="70px"
android:src="@drawable/start"
/>
<ImageButton
android:id="@+id/PauseImageButton"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_x="190px"
android:layout_y="70px"
android:src="@drawable/pause"
/>
<ImageButton
android:id="@+id/NextImageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="250px"
android:layout_y="70px"
android:src="@drawable/next"
/>
</AbsoluteLayout>

法二:播放res/raw中的音乐
public class Activity01 extends Activity{
private ImageButtonmStopImageButton;
private ImageButtonmStartImageButton;
private ImageButtonmPauseImageButton;
private TextView mTextView;

private booleanbIsReleased= false;
private booleanbIsPaused= false;
private boolean bIsPlaying= false;

public MediaPlayer mMediaPlayer = new MediaPlayer(); ;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mStopImageButton = (ImageButton) findViewById(R.id.StopImageButton);
mStartImageButton = (ImageButton) findViewById(R.id.StartImageButton);
mPauseImageButton = (ImageButton) findViewById(R.id.PauseImageButton);
mTextView = (TextView) findViewById(R.id.TextView01);
mStopImageButton.setOnClickListener(new ImageButton.OnClickListener() {//停止按钮
public void onClick(View v){
if (bIsPlaying == true){
if ( !bIsReleased ){
mMediaPlayer.stop();
mMediaPlayer.release();
bIsReleased = true;
}
bIsPlaying = false;
mTextView.setText("当前处于停止状态,请按开始进行音乐播放!");
}
}
});
mStartImageButton.setOnClickListener(new ImageButton.OnClickListener() {//开始按钮
public void onClick(View v){
try{
if ( !bIsPlaying ){
bIsPlaying = true;
mMediaPlayer = MediaPlayer.create(Activity01.this, R.raw.test);//使用create方法 装载资源中的音乐。此处还可以用create方法加载一个网络音乐
核心代码在下面的法三中。
bIsReleased = false;
mMediaPlayer.setLooping(true);//设置是否循环
try{
mMediaPlayer.prepare();
}catch (IllegalStateException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
mMediaPlayer.start();
mTextView.setText("当前正在播放音乐!");
}
}catch (IllegalStateException e){
e.printStackTrace();
}
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer arg0){
mMediaPlayer.release();
}
});
}
});
mPauseImageButton.setOnClickListener(new ImageButton.OnClickListener() {//暂停
public void onClick(View view){
if (mMediaPlayer != null){
if (bIsReleased == false){
if (bIsPaused == false){
mMediaPlayer.pause();
bIsPaused = true;
bIsPlaying = true;
mTextView.setText("已经暂停,请再次按暂停按钮回复播放!");
}else if (bIsPaused == true){
mMediaPlayer.start();
bIsPaused = false;
mTextView.setText("音乐恢复播放!");
}
}
}
}
});
}
public boolean onKeyDown(int keyCode, KeyEvent event){
if ( keyCode == KeyEvent.KEYCODE_BACK){
if ( !bIsReleased ){
mMediaPlayer.stop();
mMediaPlayer.release();
bIsReleased = true;
}
this.finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
法三:在上例中使用了create方法不仅可以加载程序中的资源的索引,还可以加载一个Uri地址,当然这就说明我们可以播放网络音乐。
其核心代码如下:
private MediaPlayer mediaPlayer;
Uri uri = Uri.parse("http://www.xxxx.com/xxx.mp3");
mediaPlayer = MediaPlayer.create(this,uri);
mediaPlayer.start();

第四部分 视频播放 VideoView
目前Android平台仅支持MP4的H.264、3GP和WMV视频的解析。
Android中内置的VideoView类可以快速制作一个系统播放器,VideoView主要用来显示一个视频文件其基本用法如下:
getBufferPercentage 得到缓冲的百分比
getCurrentPostion得到当前播放的位置
getDuration得到视频文件的时间
isPlaying是否在播放
pause暂停
resolveAdjustedSize调整视频显示大小
seekTo指定播放位置
setMediaController设置播放控制器模式(播放进度条)
setOnCompletionListener当媒体文件播放完成时触发事件
setOnErrorListener错误监听
setVideoPath设置视频源路径
setVideoURI设置视频源地址
start开始播放

方法一:通过系统自带的VideoView播放一个MP4视频文件
下来实现了播放MP4的播放。首先在布局文件中创建VideoView布局,并创建几个按钮
main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<VideoView
android:id="@+id/VideoView01"
android:layout_width="320px"
android:layout_height="240px"
/>
<Button
android:id="@+id/LoadButton"
android:layout_width="80px"
android:layout_height="wrap_content"
android:text="装载"
android:layout_x="30px"
android:layout_y="300px"
/>
<Button
android:id="@+id/PlayButton"
android:layout_width="80px"
android:layout_height="wrap_content"
android:text="播放"
android:layout_x="120px"
android:layout_y="300px"
/>
<Button
android:id="@+id/PauseButton"
android:layout_width="80px"
android:layout_height="wrap_content"
android:text="暂停"
android:layout_x="210px"
android:layout_y="300px"
/>
</AbsoluteLayout>

public class Activity01 extends Activity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

final VideoView videoView = (VideoView) findViewById(R.id.VideoView01);//创建VideoView对象
/* 操作播放的三个按钮 */
Button PauseButton = (Button) this.findViewById(R.id.PauseButton);
Button LoadButton = (Button) this.findViewById(R.id.LoadButton);
Button PlayButton = (Button) this.findViewById(R.id.PlayButton);

LoadButton.setOnClickListener(new OnClickListener() {//装载按钮事件
public void onClick(View arg0){
videoView.setVideoPath("/sdcard/test.mp4");//设置路径
videoView.setMediaController(new MediaController(Activity01.this));//设置播放进度条
videoView.requestFocus();//获取焦点
}
});
PlayButton.setOnClickListener(new OnClickListener() {//播放按钮事件
public void onClick(View arg0){
videoView.start();//开始播放
}
});
PauseButton.setOnClickListener(new OnClickListener() {//暂停按钮
public void onClick(View arg0){
videoView.pause();//暂停
}
});
}
}
方法二 自定义一个播放视频的类
原理:因为ViedoView是继承SurfaceView类的,且实现了MediaController.MediaPlayerControl接口。所以我们同样可以使用SurfaceView类来显示视频
首先在布局文件中创建一个SurfaceView。因要通过SurfaceHolder来控制SurfaceView,所以要通过getHolder方法来得到SurfaceView的SurfaceHolder对象。
如下例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:id="@+id/surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
</SurfaceView>
</LinearLayout>

public class Activity01 extends Activity implements
OnBufferingUpdateListener,
OnCompletionListener,
MediaPlayer.OnPreparedListener,
SurfaceHolder.Callback{
private static final StringTAG= "Activity01";
private intmVideoWidth;
private intmVideoHeight;
private MediaPlayermMediaPlayer;
private SurfaceViewmPreview;
private SurfaceHolderholder;
private Stringpath;
public void onCreate(Bundle icicle){
super.onCreate(icicle);
setContentView(R.layout.main);

mPreview = (SurfaceView) findViewById(R.id.surface);//得打SurfaceView对象
holder = mPreview.getHolder();//得到SurfaceHolder对象
holder.addCallback(this);//设置回调函数
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置风格
}
private void playVideo(){
try{
path = "/sdcard/test.mp4";//设置MP4路径
mMediaPlayer = new MediaPlayer();//构建MediaPlayer对象
mMediaPlayer.setDataSource(path);//设置媒体文件路径
mMediaPlayer.setDisplay(holder);//设置通过SurfaceView来显示画面
mMediaPlayer.prepare();//准备

mMediaPlayer.setOnBufferingUpdateListener(this);//设置事件监听
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}catch (Exception e){
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
public void onBufferingUpdate(MediaPlayer arg0, int percent){
Log.d(TAG, "onBufferingUpdate percent:" + percent);
}
public void onCompletion(MediaPlayer arg0){
Log.d(TAG, "onCompletion called");
}
public void onPrepared(MediaPlayer mediaplayer){
Log.d(TAG, "onPrepared called");
mVideoWidth = mMediaPlayer.getVideoWidth();
mVideoHeight = mMediaPlayer.getVideoHeight();
if (mVideoWidth != 0 && mVideoHeight != 0){
holder.setFixedSize(mVideoWidth, mVideoHeight);//设置视频的宽度和高度
mMediaPlayer.start();// 开始播放
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k){//更改时出发的事件
Log.d(TAG, "surfaceChanged called");
}
public void surfaceDestroyed(SurfaceHolder surfaceholder){// 销毁
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder){//当SurfaceHolder创建时触发
Log.d(TAG, "surfaceCreated called");
playVideo();
}
protected void onDestroy(){//销毁
super.onDestroy();
if (mMediaPlayer != null){
mMediaPlayer.release();//释放资源
mMediaPlayer = null;
}
}
}
第五部分 录音功能
录用使用的是MediaRecorder类
下例中首先在界面上放置一个ListView来显示文件列表,一个开始、一个停止按钮。当点击"开始"按钮后就构建MediaRecorder对象,并设置声音的来源(setAudioSource)、输出文件的格式
(setOutPutFormat)、音频文件的编码(setAudioEncoder)、输出文件的路径(setOutputFile)等;然后准备开始录音(prepare),开始录音(start)。最后停止录音(stop),然后释放MediaRecorder
对象(release),完成录音。
list.xml文件
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:
android="http://schemas.android.com/apk/res/android"
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>

main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
<Button
android:id="@+id/StartButton"
android:layout_width="80px"
android:layout_height="wrap_content"
android:text="开始"
android:layout_x="70px"
android:layout_y="100px"
/>
<Button
android:id="@+id/StopButton"
android:layout_width="80px"
android:layout_height="wrap_content"
android:text="停止"
android:layout_x="170px"
android:layout_y="100px"
/>
</AbsoluteLayout>

public class Activity01 extends ListActivity{
private ButtonStartButton;
private ButtonStopButton;

private FilemRecAudioFile;//录制的音频文件
private FilemRecAudioPath;//SD卡路径
private MediaRecordermMediaRecorder;//MediaRecorder对象
private List<String>mMusicList= new ArrayList<String>();//录音文件列表
private StringstrTempFile= "recaudio_";//零时文件的前缀

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

StartButton = (Button) findViewById(R.id.StartButton);
StopButton = (Button) findViewById(R.id.StopButton);

if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){//检测是否存在SD卡
mRecAudioPath = Environment.getExternalStorageDirectory();//通过getExternalStorageDirectory()得到SD卡的路径
musicList();//更新所有录音文件到List中
}else{
Toast.makeText(Activity01.this, "没有SD卡", Toast.LENGTH_LONG).show();
}
StartButton.setOnClickListener(new Button.OnClickListener() {//开始按钮事件监听
@Override
public void onClick(View arg0){
try{
mRecAudioFile = File.createTempFile(strTempFile, ".amr", mRecAudioPath);//创建录音文件
mMediaRecorder = new MediaRecorder();//实例化MediaRecorder对象
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//设置麦克风
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);//设置输出文件的格式
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);//设置音频文件的编码
mMediaRecorder.setOutputFile(mRecAudioFile.getAbsolutePath());//设置输出文件的路径
mMediaRecorder.prepare();//准备
mMediaRecorder.start();//开始
}catch (IOException e){
e.printStackTrace();
}
}
});
StopButton.setOnClickListener(new Button.OnClickListener() {//停止按钮事件监听
@Override
public void onClick(View arg0){
if (mRecAudioFile != null){

mMediaRecorder.stop();//停止录音
mMusicList.add(mRecAudioFile.getName());//将录音文件添加到List中
ArrayAdapter<String> musicList = new ArrayAdapter<String>(Activity01.this, R.layout.list, mMusicList);
setListAdapter(musicList);

mMediaRecorder.release();//释放MediaRecorder
mMediaRecorder = null;
}
}
});
}
private void playMusic(File file){//播放录音文件
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "audio");//设置文件类型
startActivity(intent);
}
protected void onListItemClick(ListView l, View v, int position, long id){//当我们点击列表时,播放被点击的音乐
File playfile = new File(mRecAudioPath.getAbsolutePath() + File.separator + mMusicList.get(position));//得到被点击的文件
playMusic(playfile);// 播放
}
public void musicList(){//播放列表
// 取得指定位置的文件设置显示到播放列表
File home = mRecAudioPath;
if (home.listFiles(new MusicFilter()).length > 0){
for (File file : home.listFiles(new MusicFilter())){
mMusicList.add(file.getName());
}
ArrayAdapter<String> musicList = new ArrayAdapter<String>(Activity01.this, R.layout.list, mMusicList);
setListAdapter(musicList);
}
}
}

class MusicFilter implements FilenameFilter{//过滤文件类型
public boolean accept(File dir, String name){
return (name.endsWith(".amr"));//文件保存在SD卡中为amr文件格式 查看:DDMS---File Explorer---sdcartd中
}
}
第六部分 相机设置
在Android中专门提供了Camera类来处理相机事件,是一个专门用来连接和断开相机服务的类。
Camera 有如下事件
Camera.AutoFocusCallback 自动调焦功能
Camera.ErrorCallback错误信息扑捉
Camera.Parameters相机的属性参数
Camera.PictureCallback拍照、产生图片时触发
Camera.PreviewCallback相机预览设置
Camera.ShutterCallback快门设置
Camera.Size图片的尺寸

Camera类的方法:
autoFocus设置自动对焦
getParameters得到相机的参数
open启动相机服务
release释放相机服务
setParameters设置预览参数
setPreviewDisplay设置预览
startPreview开始预览
stopPreview停止预览
takePicture拍照
Camera没有构造方法,要使用它可直接通过open方法来打开相机设备,然后通过Camera.Parameters对相机的一些属性进行设置,如图片的格式,大小等。
takePicture拍照方法的使用要实现3个回调函数,即Camera.ShutterCallback(快门)和两个Camera.PictureCallback(图像数据)。
拍照后要取得图像数据要实现Camera.PictureCallback的onPictureTaken方法(此方法第一个参数就是图像数据,第二个参数是相机)
下面为一个相机拍照例子。相机需要一个界面来预览当前拍摄的效果,这里可以使用SurfaceView类。最后将照片保存到SD开中(注意:确定SD卡已经插入)

public class Activity01 extends Activity{
private PreviewmPreview;

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);
mPreview = new Preview(this);//创建预览视图
setContentView(mPreview);//设置显示
}
public boolean onKeyUp(int keyCode, KeyEvent event){
switch (keyCode){
case KeyEvent.KEYCODE_DPAD_CENTER:
mPreview.takePicture();
break;
}
return true;
}
}

class Preview extends SurfaceView implements SurfaceHolder.Callback{ //显示预览
SurfaceHolder mHolder;
Camera mCamera;
Bitmap CameraBitmap;

Preview(Context context){
super(context);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();//启动Camera
try {
mCamera.setPreviewDisplay(holder);
}catch (IOException exception) {
mCamera.release();//释放mCamera
mCamera = null;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();//停止预览
mCamera = null;
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();//构建Camera.Parameters对相机的参数进行设置
parameters.setPictureFormat(PixelFormat.JPEG);//设置拍照的图片格式
parameters.setPreviewSize(320, 480);//设置Preview的尺寸
//parameters.setPictureSize(320, 480);//设置图像分辨率
mCamera.setParameters(parameters);//设置相机的预览参数
mCamera.startPreview();// 开始预览
}
public void takePicture(){//拍照片
if (mCamera != null){
mCamera.takePicture(null, null, jpegCallback);
}
}
private PictureCallback jpegCallback = new PictureCallback(){//拍照后输出图片
public void onPictureTaken(byte[] _data, Camera _camera){//第一个参数就是图像数据,第二个参数是相机
// 处理的JPEG数据资源
CameraBitmap = BitmapFactory.decodeByteArray(_data, 0, _data.length);
File myCaptureFile = new File("/sdcard/camera1.jpg");
try{
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
CameraBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();//冲洗照片
bos.close();
/* 将拍到的图片绘制出来 */
Canvas canvas= mHolder.lockCanvas();
canvas.drawBitmap(CameraBitmap, 0, 0, null);
mHolder.unlockCanvasAndPost(canvas);
}catch (Exception e){
e.getMessage();
}
}
};
}
第七部分 闹钟的设置
在Android中可以通过AlarmManager来实现闹钟,AlarmManager类是专门用来设定在某个指定的时间去完成指定的事件。
AlarmManager提供了访问系统警报的服务,只要在程序中设置了警报服务,AlarmManger就会通过onReceive()方法去执行这些事件,就算系统处于待机状态,同样不会影响运行。可
通过Context.getSystemService方法来获得改服务。
AlarmManager的方法:
cancel取消AlarmManager服务
set设置AlarmManager服务
setInexactRepeating设置不精确周期
setRepeating设置精确周期
setTimeZone设置时区
要实现闹钟,首先需要创建一个继承BroadcastReceiver的类,实现onReceive方法来接收这个Alarm服务,然后通过建立Intent和PendingIntent连接来调用Alarm组件。
下例中我们点击"设置闹钟"按钮时,通过TimePickerDialog来设置时间。
main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<Button
android:id="@+id/Button01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="设置闹钟"
/>
<Button
android:id="@+id/Button02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="取消闹钟"
/>
</LinearLayout>

public class AlarmReceiver extends BroadcastReceiver{//创建接收Alarm服务的AlarmReceiver类。因使用了BroadcastReceiver服务,需要在AndroidManifest.xml中进行声明
代码如:<receiver android:name = ".AlarmReceiver" android:process =":remote"/>
public void onReceive(Context context, Intent intent){
Toast.makeText(context, "你设置的闹钟时间到了", Toast.LENGTH_LONG).show();
}
}
public class Activity01 extends Activity{
ButtonmButton1;
ButtonmButton2;
TextView mTextView;
Calendar calendar;

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

calendar=Calendar.getInstance();

mTextView=(TextView)findViewById(R.id.TextView01);
mButton1=(Button)findViewById(R.id.Button01);
mButton2=(Button)findViewById(R.id.Button02);

mButton1.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
calendar.setTimeInMillis(System.currentTimeMillis());
int mHour=calendar.get(Calendar.HOUR_OF_DAY);
int mMinute=calendar.get(Calendar.MINUTE);
new TimePickerDialog(Activity01.this,
new TimePickerDialog.OnTimeSetListener(){
public void onTimeSet(TimePicker view,int hourOfDay,int minute){
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,hourOfDay);
calendar.set(Calendar.MINUTE,minute);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND,0);
/* 建立Intent和PendingIntent,来调用目标组件 */
Intent intent = new Intent(Activity01.this, AlarmReceiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(Activity01.this,0, intent, 0);
AlarmManager am;
am = (AlarmManager)getSystemService(ALARM_SERVICE);//获取闹钟管理的实例
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);//设置闹钟
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (10*1000), (24*60*60*1000), pendingIntent); //设置周期闹
String tmpS="设置闹钟时间为"+format(hourOfDay)+":"+format(minute);
mTextView.setText(tmpS);
}
},mHour,mMinute,true).show();
}
});
mButton2.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Intent intent = new Intent(Activity01.this, AlarmReceiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(Activity01.this,0, intent, 0);
AlarmManager am;
am =(AlarmManager)getSystemService(ALARM_SERVICE);//获取闹钟管理的实例
am.cancel(pendingIntent);//取消闹钟设置
mTextView.setText("闹钟已取消!");
}
});
}
private String format(int x){//格式化字符串(7:3->07:03)
String s = "" + x;
if (s.length() == 1){
s = "0" + s;
}
return s;
}
}
第八部分 铃声设置
在Android中可通过RingtoneManager类专门来操作各种铃声,比如来的铃声,闹钟铃声以及警告和通知铃声。
Android自带的系统铃声都放置在"/system/medio/audio"文件中,自己下载的铃声都在SD卡中,那么就要在SD卡中建立如下文件目录
/sdcard/music/ringtones: 一般铃声 (来电铃声)
/sdcard/music/alarms: 闹钟铃声
/sdcard/music/notificaitons: 警告或通知铃声
可在DDMS ---File Explorer---sdcard中查看
RingtoneManager类的常用方法
getActualDefaultRingtoneUri取得指定类型当前默认的铃声
getCursor返回所有可用铃声的游标
getDefaultType得到指定URI默认的铃声类型
getRingtone获得当前游标所指定的铃声,返回指定铃声的URI
getDefaultUri返回指定类型默认铃声的URI
getRingtonePosition得到指定铃声的位置
getRingtongUri获得得到指定位置的铃声URI
getValidRingtoneUri得到一个可用铃声的URI
idDefault得到指定的URI是否是默认的铃声
setActualDefaultRingtoneUri设置默认的铃声
例:
public class Activity01 extends Activity{
private Button mButtonRingtone;//3个按钮
private Button mButtonAlarm;
private Button mButtonNotification;

public static final int ButtonRingtone= 0;//来电铃声
public static final int ButtonAlarm= 1;//警报铃声
public static final int ButtonNotification= 2;//通知铃声

private String strRingtoneFolder = "/sdcard/music/ringtones";//来电铃声文件夹
private String strAlarmFolder = "/sdcard/music/alarms";//警报铃声文件夹
private String strNotificationFolder = "/sdcard/music/notifications";//通知铃声文件夹

public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

mButtonRingtone = (Button) findViewById(R.id.ButtonRingtone);
mButtonAlarm = (Button) findViewById(R.id.ButtonAlarm);
mButtonNotification = (Button) findViewById(R.id.ButtonNotification);

mButtonRingtone.setOnClickListener(new Button.OnClickListener(){//设置来电铃声
@Override
public void onClick(View arg0){
if (bFolder(strRingtoneFolder)){
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);//打开系统铃声设置
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);//类型为来电RINGTONE
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "设置来电铃声");//设置显示的title
startActivityForResult(intent, ButtonRingtone);//当设置完成之后开启并返回到当前的Activity
}
}
});
mButtonAlarm.setOnClickListener(new Button.OnClickListener(){//设置闹钟铃声
@Override
public void onClick(View arg0){
if (bFolder(strAlarmFolder)){
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);//打开系统铃声设置
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM);//设置铃声类型和title
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "设置闹铃铃声");
startActivityForResult(intent, ButtonAlarm);//当设置完成之后返回到当前的Activity
}
}
});
mButtonNotification.setOnClickListener(new Button.OnClickListener(){//设置通知铃声
@Override
public void onClick(View arg0){
if (bFolder(strNotificationFolder)){
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);//打开系统铃声设置
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);//设置铃声类型和title
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "设置通知铃声");
startActivityForResult(intent, ButtonNotification);//当设置完成之后返回到当前的Activity
}
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data){//设置铃声之后的回调函数。当选择了需要设置为铃声的音乐后,系统会调用onActivityResult
方法来处理我们所进行的设置,所有需要重写onActivityResult,并根据设置的不同类型的铃声来
告诉系统我们的设置。
if (resultCode != RESULT_OK){
return;
}switch (requestCode){
case ButtonRingtone:
try{
Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);//得到我们选择的铃声
if (pickedUri != null){
RingtoneManager.setActualDefaultRingtoneUri(Activity01.this, RingtoneManager.TYPE_RINGTONE, pickedUri);//将我们选择的铃声设置成为默认
}
}catch (Exception e){
}
break;
case ButtonAlarm:
try{
Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);//得到我们选择的铃声
if (pickedUri != null){
RingtoneManager.setActualDefaultRingtoneUri(Activity01.this, RingtoneManager.TYPE_ALARM, pickedUri);//将我们选择的铃声设置成为默认
}
}catch (Exception e){
}
break;
case ButtonNotification:
try{
Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);//得到我们选择的铃声
if (pickedUri != null){
RingtoneManager.setActualDefaultRingtoneUri(Activity01.this, RingtoneManager.TYPE_NOTIFICATION, pickedUri);//将我们选择的铃声设置成为默认
}
}catch (Exception e){
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
private boolean bFolder(String strFolder){//检测是否存在指定的文件夹,如果不存在则创建
boolean btmp = false;
File f = new File(strFolder);
if (!f.exists()){
if (f.mkdirs()){
btmp = true;
}else{
btmp = false;
}
}else{
btmp = true;
}
return btmp;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值