说到移动设备,里面的多媒体资源想必是很多人的兴趣所在,多媒体资源一般包括视频、音频和图片等。本节主要讲Android开发中访问和操作音频与视频的方法。

       Android为音频和视频操作分别提供了MediaPlayer类和MediaRecorder类这两个工具类,本文就为大家演示如何使用这两个类操作音频和视频。

       一、简单音乐播放器

       1、新建一个项目Lesson28_Music,主Activity的名字是MainMusic.java。

       2、拷贝以下这几张图片到res/drawable目录下,并建立3个xml文件,拷贝love.mp3到res/raw文件中。

play play disable pause pause disable stop stop disable

       play.xml:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <SELECTOR xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <ITEM android:state_enabled="false" android:drawable="@drawable/play_disable" /> <!-- state_enabled=false -->  
  4.     <ITEM android:drawable="@drawable/play_50" /> <!-- default -->  
  5. </SELECTOR>  

       pause.xml:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <SELECTOR xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <ITEM android:state_enabled="false" android:drawable="@drawable/pause_disable" /> <!-- state_enabled=false -->  
  4.     <ITEM android:drawable="@drawable/pause_50" /> <!-- default -->  
  5. </SELECTOR>  

       stop.xml:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <SELECTOR xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <ITEM android:state_enabled="false" android:drawable="@drawable/stop_disable" /> <!-- state_enabled=false -->  
  4.     <ITEM android:drawable="@drawable/stop_50" /> <!-- default -->  
  5. </SELECTOR>  

       3、res/layout/main.xml 的内容如下:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LINEARLAYOUT xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical">  
  3.     <TEXTVIEW android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="简单音乐播放器" android:textsize="25sp" />  
  4. </LINEARLAYOUT>  
  5. <LINEARLAYOUT xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="horizontal">  
  6.   
  7.         <IMAGEBUTTON android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/play" android:id="@+id/play" android:adjustviewbounds="true" android:layout_margin="4dp">  
  8.         </IMAGEBUTTON>  
  9.   
  10.         <IMAGEBUTTON android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/pause" android:id="@+id/pause" android:adjustviewbounds="true" android:layout_margin="4dp">  
  11.         </IMAGEBUTTON>  
  12.   
  13.         <IMAGEBUTTON android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/stop" android:id="@+id/stop" android:adjustviewbounds="true" android:layout_margin="4dp">  
  14.         </IMAGEBUTTON>  
  15. </LINEARLAYOUT>  

       4、MainMusic.java的内容如下:

Java代码
  1. package android.basic.lesson28;   
  2.   
  3. import java.io.IOException;   
  4.   
  5. import android.app.Activity;   
  6. import android.media.MediaPlayer;   
  7. import android.media.MediaPlayer.OnCompletionListener;   
  8. import android.media.MediaPlayer.OnPreparedListener;   
  9. import android.os.Bundle;   
  10. import android.view.View;   
  11. import android.view.View.OnClickListener;   
  12. import android.widget.ImageButton;   
  13. import android.widget.Toast;   
  14.   
  15. public class MainMusic extends Activity {   
  16.   
  17.     // 声明变量   
  18.     private ImageButton play, pause, stop;   
  19.     private MediaPlayer mPlayer;   
  20.   
  21.     /** Called when the activity is first created. */  
  22.     @Override  
  23.     public void onCreate(Bundle savedInstanceState) {   
  24.         super.onCreate(savedInstanceState);   
  25.         setContentView(R.layout.main);   
  26.   
  27.         // 定义UI组件   
  28.         play = (ImageButton) findViewById(R.id.play);   
  29.         pause = (ImageButton) findViewById(R.id.pause);   
  30.         stop = (ImageButton) findViewById(R.id.stop);   
  31.   
  32.         // 按钮先全部失效   
  33.         play.setEnabled(false);   
  34.         pause.setEnabled(false);   
  35.         stop.setEnabled(false);   
  36.   
  37.         // 定义单击监听器   
  38.         OnClickListener ocl = new View.OnClickListener() {   
  39.   
  40.             @Override  
  41.             public void onClick(View v) {   
  42.                 switch (v.getId()) {   
  43.                 case R.id.play:   
  44.                     // 播放   
  45.                     Toast.makeText(MainMusic.this"点击播放", Toast.LENGTH_SHORT).show();   
  46.                     play();   
  47.                     break;   
  48.                 case R.id.pause:   
  49.                     // 暂停   
  50.                     Toast.makeText(MainMusic.this"暂停播放", Toast.LENGTH_SHORT).show();   
  51.                     pause();   
  52.                     break;   
  53.                 case R.id.stop:   
  54.                     // 停止   
  55.                     Toast.makeText(MainMusic.this"停止播放", Toast.LENGTH_SHORT).show();   
  56.                     stop();   
  57.                     break;   
  58.                 }   
  59.             }   
  60.         };   
  61.   
  62.         // 绑定单击监听   
  63.         play.setOnClickListener(ocl);   
  64.         pause.setOnClickListener(ocl);   
  65.         stop.setOnClickListener(ocl);   
  66.   
  67.         // 初始化   
  68.         initMediaPlayer();   
  69.     }   
  70.   
  71.     // 初始化播放器   
  72.     private void initMediaPlayer() {   
  73.   
  74.         // 定义播放器   
  75.         mPlayer = MediaPlayer.create(getApplicationContext(), R.raw.love);   
  76.   
  77.         // 定义资源准备好的监听器   
  78.         mPlayer.setOnPreparedListener(new OnPreparedListener() {   
  79.             @Override  
  80.             public void onPrepared(MediaPlayer mp) {   
  81.                 // 资源准备好了再让播放器按钮有效   
  82.                 Toast.makeText(MainMusic.this"onPrepared", Toast.LENGTH_SHORT)   
  83.                         .show();   
  84.                 play.setEnabled(true);   
  85.             }   
  86.         });   
  87.   
  88.         // 定义播放完成监听器   
  89.         mPlayer.setOnCompletionListener(new OnCompletionListener() {   
  90.   
  91.             @Override  
  92.             public void onCompletion(MediaPlayer mp) {   
  93.                 Toast.makeText(MainMusic.this"onCompletion",   
  94.                         Toast.LENGTH_SHORT).show();   
  95.                 stop();   
  96.             }   
  97.         });   
  98.     }   
  99.   
  100.     // 停止播放   
  101.     private void stop() {   
  102.         mPlayer.stop();   
  103.         pause.setEnabled(false);   
  104.         stop.setEnabled(false);   
  105.         try {   
  106.             mPlayer.prepare();   
  107.             mPlayer.seekTo(0);   
  108.             play.setEnabled(true);   
  109.         } catch (IllegalStateException e) {   
  110.             e.printStackTrace();   
  111.         } catch (IOException e) {   
  112.             e.printStackTrace();   
  113.         }   
  114.   
  115.     }   
  116.   
  117.     // 播放   
  118.     private void play() {   
  119.   
  120.         mPlayer.start();   
  121.         play.setEnabled(false);   
  122.         pause.setEnabled(true);   
  123.         stop.setEnabled(true);   
  124.     }   
  125.   
  126.     // 暂停   
  127.     private void pause() {   
  128.         mPlayer.pause();   
  129.         play.setEnabled(true);   
  130.         pause.setEnabled(false);   
  131.         stop.setEnabled(true);   
  132.     }   
  133.   
  134.     // Activity销毁前停止播放   
  135.     @Override  
  136.     protected void onDestroy() {   
  137.         super.onDestroy();   
  138.         if (stop.isEnabled()) {   
  139.             stop();   
  140.         }   
  141.   
  142.     }   
  143.   
  144. }  

       5、运行程序,查看效果。

简单音乐播放器

简单音乐播放器暂停播放

       二、简单视频播放器

       Android为视频播放提供了VideoView和MediaController两个现成的组件,让我们可以方便的实现MP4、3GP等视频的播放。下面我们通过一个例子来看一下:

       1、新建一个项目Lesson28_Video。

       2、使用Format Factory这个软件压缩一个视频备用,我这里压缩的参数如下:

Format Factory压缩视频的参数

       注意,如果播放时完全无法播放或者只有声音没有图像,你就需要换压缩软件和调整压缩参数重新压缩视频了,暂时只能这样,我也是折腾了2-3小时都是黑屏,郁闷中(似乎得出一个答案,是否黑屏和机器设备的性能有关,我降低压缩分辨率和每秒帧数,出图像音画同步,如果提高每秒帧数,声音出来后十几秒图像才会出来,但是出来后音画还是同步的,有兴趣的朋友可以多测试测试给出一个结论)。

       用命令行的方式拷贝此视频到存储卡(sdcard)中,为什么不用eclipse中的可视化工具拷贝呢?因为那个方式靠大文件的时候经常失败,而命令行方式我没拷贝失败一次过。命令就是 adb push ,具体截个图给你看:

命令行拷贝视频到sd卡

       3、res\layout\main.xml的内容如下:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LINEARLAYOUT xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" android:layout_gravity="top">  
  3. <VIDEOVIEW android:layout_height="fill_parent" android:layout_width="fill_parent" android:id="@+id/VideoView01">  
  4. </VIDEOVIEW>  
  5. </LINEARLAYOUT>  

       4、MainVideo.java的内容如下:

Java代码
  1. package android.basic.lesson28;   
  2.   
  3. import android.app.Activity;   
  4. import android.net.Uri;   
  5. import android.os.Bundle;   
  6. import android.view.Window;   
  7. import android.view.WindowManager;   
  8. import android.widget.MediaController;   
  9. import android.widget.VideoView;   
  10.   
  11. public class MainVideo extends Activity {   
  12.     /** Called when the activity is first created. */  
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {   
  15.         super.onCreate(savedInstanceState);   
  16.         //全屏   
  17.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);   
  18.         //标题去掉   
  19.         this.requestWindowFeature(Window.FEATURE_NO_TITLE);   
  20.         //要在全屏等设置完毕后再加载布局   
  21.         setContentView(R.layout.main);   
  22.   
  23.         //定义UI组件   
  24.         VideoView videoView = (VideoView) findViewById(R.id.VideoView01);   
  25.         //定义MediaController对象   
  26.         MediaController mediaController = new MediaController(this);   
  27.         //把MediaController对象绑定到VideoView上   
  28.         mediaController.setAnchorView(videoView);   
  29.         //设置VideoView的控制器是mediaController   
  30.         videoView.setMediaController(mediaController);   
  31.   
  32.         //这两种方法都可以 videoView.setVideoPath("file:///sdcard/love_480320.mp4");   
  33.         videoView.setVideoURI(Uri.parse("/sdcard/love_480320.mp4"));   
  34.         //启动后就播放   
  35.         videoView.start();   
  36.     }   
  37. }  

       5、运行效果如下:

简单视频播放器

简单视频播放器播放

       三、简单录音程序

       1、新建一个一个项目Tip_Recorder,主activity名字是MainActivity。

       2、其布局文件main.xml的代码是:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LINEARLAYOUT xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" android:gravity="center">  
  3.   
  4.     <BUTTON type=submit android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="录音" android:textsize="30sp" android:id="@+id/Button01"></BUTTON>  
  5.     <BUTTON type=submit android:layout_height="wrap_content" android:layout_width="wrap_content" android:text="停止" android:textsize="30sp" android:id="@+id/Button02" android:layout_margintop="20dp"></BUTTON>  
  6. </LINEARLAYOUT>  

       3、主程序文件 MainActivity.java的代码如下:

Java代码
  1. package android.tip.yaoyao;   
  2.   
  3. import java.io.File;   
  4. import java.io.IOException;   
  5. import java.util.Calendar;   
  6. import java.util.Locale;   
  7.   
  8. import android.app.Activity;   
  9. import android.media.MediaRecorder;   
  10. import android.os.Bundle;   
  11. import android.text.format.DateFormat;   
  12. import android.view.View;   
  13. import android.widget.Button;   
  14. import android.widget.Toast;   
  15.   
  16. public class MainActivity extends Activity {   
  17.   
  18.     private Button recordButton;   
  19.     private Button stopButton;   
  20.   
  21.     private MediaRecorder mr;   
  22.   
  23.     @Override  
  24.     public void onCreate(Bundle savedInstanceState) {   
  25.         super.onCreate(savedInstanceState);   
  26.         setContentView(R.layout.main);   
  27.   
  28.         recordButton = (Button) this.findViewById(R.id.Button01);   
  29.         stopButton = (Button) this.findViewById(R.id.Button02);   
  30.   
  31.         // 录音按钮点击事件   
  32.         recordButton.setOnClickListener(new View.OnClickListener() {   
  33.   
  34.             @Override  
  35.             public void onClick(View v) {   
  36.   
  37.                 File file = new File("/sdcard/"  
  38.                         + "YY"  
  39.                         + new DateFormat().format("yyyyMMdd_hhmmss",   
  40.                                 Calendar.getInstance(Locale.CHINA)) + ".amr");   
  41.   
  42.                 Toast.makeText(getApplicationContext(), "正在录音,录音文件在"+file.getAbsolutePath(), Toast.LENGTH_LONG)   
  43.                         .show();   
  44.   
  45.                 // 创建录音对象   
  46.                 mr = new MediaRecorder();   
  47.   
  48.                 // 从麦克风源进行录音   
  49.                 mr.setAudioSource(MediaRecorder.AudioSource.DEFAULT);   
  50.   
  51.                 // 设置输出格式   
  52.                 mr.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);   
  53.   
  54.                 // 设置编码格式   
  55.                 mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);   
  56.   
  57.                 // 设置输出文件   
  58.                 mr.setOutputFile(file.getAbsolutePath());   
  59.   
  60.                 try {   
  61.                     // 创建文件   
  62.                     file.createNewFile();   
  63.                     // 准备录制   
  64.                     mr.prepare();   
  65.                 } catch (IllegalStateException e) {   
  66.                     e.printStackTrace();   
  67.                 } catch (IOException e) {   
  68.                     e.printStackTrace();   
  69.                 }   
  70.                 // 开始录制   
  71.                 mr.start();   
  72.                 recordButton.setText("录音中……");   
  73.             }   
  74.         });   
  75.   
  76.         // 停止按钮点击事件   
  77.         stopButton.setOnClickListener(new View.OnClickListener() {   
  78.   
  79.             @Override  
  80.             public void onClick(View v) {   
  81.   
  82.                 if (mr != null) {   
  83.                     mr.stop();   
  84.                     mr.release();   
  85.                     mr = null;   
  86.                     recordButton.setText("录音");   
  87.                     Toast.makeText(getApplicationContext(), "录音完毕", Toast.LENGTH_LONG).show();   
  88.                 }   
  89.             }   
  90.         });   
  91.   
  92.     }   
  93.   
  94. }  

       4、因为录音和写存储卡都需要权限声明,所以这里也把AndroidManifest.xml代码提供出来:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <MANIFEST android:versionname="1.0" android:versioncode="1" xmlns:android="http://schemas.android.com/apk/res/android" package="android.tip.yaoyao">  
  3.     <APPLICATION android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">  
  4.         <ACTIVITY android:name=".MainActivity" android:label="@string/app_name" android:screenorientation="portrait" android:configchanges="orientation|keyboardHidden|keyboard">  
  5.             <INTENT -filter>  
  6.                 <ACTION android:name="android.intent.action.MAIN" />  
  7.                 <CATEGORY android:name="android.intent.category.LAUNCHER" />  
  8.             </INTENT>  
  9.         </ACTIVITY>  
  10.   
  11.     </APPLICATION>  
  12.     <USES android:minsdkversion="4" -sdk />  
  13.   
  14. <USES android:name="android.permission.RECORD_AUDIO" -permission></USES>  
  15. <USES android:name="android.permission.WRITE_EXTERNAL_STORAGE" -permission></USES>  
  16. </MANIFEST>   

       5、编译并运行程序,查看结果。

简单录音程序

       点击录音:

简单录音程序录音中

       录音文件在存储卡的根目录几个以YY开头的amr文件:

录音文件在sd卡中的目录


       6、这个例子要用到录音设备,而模拟器并不能把电脑声卡模拟出来使用,因此这个例子必须在真机上进行测试。

       真机上测试方法也很简单:

       1)在真机上把USB调试模式打开。

       2)把真机用USB线与电脑连接。

       3)设置电脑和手机的连接方式为 ”仅充电“(此时手机可以操作存储卡)。

       4)打开Eclipse,在不选择模拟器的情况下运行程序,此时,Eclipse会自动找到真机,并使用它运行程序,最完美的是他可以把真机运行程序的输出信息,照样输出在Eclipse中的Logcat日志中。

       上面的真机截图也是通过Eclipse的DDMS窗口直接抓取的,下图中右上角颜色最深的图标就是抓取真机截图的按钮:

DDMS截图按钮

       本节就讲到这里,内容不少,希望大家自己多加练习,熟练掌握。

本文发布:Android开发网
本文地址:http://www.teaching4real.com/android/course/198.html
2012年9月11日
发布:鸡啄米 分类:Android开发教程 浏览: 注册送白菜网:1