本文介绍MediaPlayer的使用。MediaPlayer可以播放音频和视频,另外也可以通过VideoView来播放视频,虽然VideoView比MediaPlayer简单易用,但定制性不如用MediaPlayer,要视情况选择了。MediaPlayer播放音频比较简单,但是要播放视频就需要SurfaceView。SurfaceView比普通的自定义View更有绘图上的优势,它支持完全的OpenGL ES库。

先贴出本文程序运行结果的截图,上面是播放/停止音频,可用SeekBar来调进度,下面是播放/停止视频,也是用SeekBar来调进度:

main.xml的源码:

XML/HTML代码
  1. <linearlayout android:id="@+id/LinearLayout01"
  2. android:layout_width="fill_parent" android:layout_height="fill_parent"
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:orientation="vertical">
  5. <seekbar android:id="@+id/SeekBar01" android:layout_height="wrap_content"
  6. android:layout_width="fill_parent">
  7. <linearlayout android:id="@+id/LinearLayout02"
  8. android:layout_width="wrap_content" android:layout_height="wrap_content">
  9. <button android:id="@+id/Button01" android:layout_width="wrap_content"
  10. android:layout_height="wrap_content" android:text="播放音频">
  11. <button android:id="@+id/Button02" android:layout_width="wrap_content"
  12. android:layout_height="wrap_content" android:text="停止播放">
  13. <seekbar android:id="@+id/SeekBar02" android:layout_height="wrap_content"
  14. android:layout_width="fill_parent">
  15. <surfaceview android:id="@+id/SurfaceView01"
  16. android:layout_width="fill_parent" android:layout_height="250px">
  17. <linearlayout android:id="@+id/LinearLayout02"
  18. android:layout_width="wrap_content" android:layout_height="wrap_content">
  19. <button android:layout_width="wrap_content"
  20. android:layout_height="wrap_content" android:id="@+id/Button03"
  21. android:text="播放视频">
  22. <button android:layout_width="wrap_content"
  23. android:layout_height="wrap_content" android:text="停止播放" android:id="@+id/Button04">

本文程序的源码,有点长:

Java代码
  1. package com.testMedia;
  2. import java.io.IOException;
  3. import java.util.Timer;
  4. import java.util.TimerTask;
  5. import android.app.Activity;
  6. import android.media.AudioManager;
  7. import android.media.MediaPlayer;
  8. import android.os.Bundle;
  9. import android.view.SurfaceHolder;
  10. import android.view.SurfaceView;
  11. import android.view.View;
  12. import android.widget.Button;
  13. import android.widget.SeekBar;
  14. import android.widget.Toast;
  15. public class testMedia extends Activity {
  16. /** Called when the activity is first created. */
  17. private SeekBar skb_audio=null;
  18. private Button btn_start_audio = null;
  19. private Button btn_stop_audio = null;
  20. private SeekBar skb_video=null;
  21. private Button btn_start_video = null;
  22. private Button btn_stop_video = null;
  23. private SurfaceView surfaceView;
  24. private SurfaceHolder surfaceHolder;
  25. private MediaPlayer m = null;
  26. private Timer mTimer;
  27. private TimerTask mTimerTask;
  28. private boolean isChanging=false;//互斥变量,防止定时器与SeekBar拖动时进度冲突
  29. @Override
  30. public void onCreate(Bundle savedInstanceState) {
  31. super.onCreate(savedInstanceState);
  32. setContentView(R.layout.main);
  33. //----------Media控件设置---------//
  34. m=new MediaPlayer();
  35. //播放结束之后弹出提示
  36. m.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
  37. @Override
  38. public void onCompletion(MediaPlayer arg0) {
  39. Toast.makeText(testMedia.this, "结束", 1000).show();
  40. m.release();
  41. }
  42. });
  43. //----------定时器记录播放进度---------//
  44. mTimer = new Timer();
  45. mTimerTask = new TimerTask() {
  46. @Override
  47. public void run() {
  48. if(isChanging==true)
  49. return;
  50. if(m.getVideoHeight()==0)
  51. skb_audio.setProgress(m.getCurrentPosition());
  52. else
  53. skb_video.setProgress(m.getCurrentPosition());
  54. }
  55. };
  56. mTimer.schedule(mTimerTask, 0, 10);
  57. btn_start_audio = (Button) this.findViewById(R.id.Button01);
  58. btn_stop_audio = (Button) this.findViewById(R.id.Button02);
  59. btn_start_audio.setOnClickListener(new ClickEvent());
  60. btn_stop_audio.setOnClickListener(new ClickEvent());
  61. skb_audio=(SeekBar)this.findViewById(R.id.SeekBar01);
  62. skb_audio.setOnSeekBarChangeListener(new SeekBarChangeEvent());
  63. btn_start_video = (Button) this.findViewById(R.id.Button03);
  64. btn_stop_video = (Button) this.findViewById(R.id.Button04);
  65. btn_start_video.setOnClickListener(new ClickEvent());
  66. btn_stop_video.setOnClickListener(new ClickEvent());
  67. skb_video=(SeekBar)this.findViewById(R.id.SeekBar02);
  68. skb_video.setOnSeekBarChangeListener(new SeekBarChangeEvent());
  69. surfaceView = (SurfaceView) findViewById(R.id.SurfaceView01);
  70. surfaceHolder = surfaceView.getHolder();
  71. surfaceHolder.setFixedSize(100, 100);
  72. surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  73. }
  74. /*
  75. * 按键事件处理
  76. */
  77. class ClickEvent implements View.OnClickListener{
  78. @Override
  79. public void onClick(View v) {
  80. if(v==btn_start_audio)
  81. {
  82. m.reset();//恢复到未初始化的状态
  83. m=MediaPlayer.create(testMedia.this, R.raw.big);//读取音频
  84. skb_audio.setMax(m.getDuration());//设置SeekBar的长度
  85. try {
  86. m.prepare();        //准备
  87. } catch (IllegalStateException e) {
  88. // TODO Auto-generated catch block
  89. e.printStackTrace();
  90. } catch (IOException e) {
  91. // TODO Auto-generated catch block
  92. e.printStackTrace();
  93. }
  94. m.start();        //播放
  95. }
  96. else if(v==btn_stop_audio || v==btn_stop_video)
  97. {
  98. m.stop();
  99. }
  100. else if(v==btn_start_video)
  101. {
  102. m.reset();//恢复到未初始化的状态
  103. m=MediaPlayer.create(testMedia.this, R.raw.test);//读取视频
  104. skb_video.setMax(m.getDuration());//设置SeekBar的长度
  105. m.setAudioStreamType(AudioManager.STREAM_MUSIC);
  106. m.setDisplay(surfaceHolder);//设置屏幕
  107. try {
  108. m.prepare();
  109. } catch (IllegalArgumentException e) {
  110. // TODO Auto-generated catch block
  111. e.printStackTrace();
  112. } catch (IllegalStateException e) {
  113. // TODO Auto-generated catch block
  114. e.printStackTrace();
  115. } catch (IOException e) {
  116. // TODO Auto-generated catch block
  117. e.printStackTrace();
  118. }
  119. m.start();
  120. }
  121. }
  122. }
  123. /*
  124. * SeekBar进度改变事件
  125. */
  126. class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener{
  127. @Override
  128. public void onProgressChanged(SeekBar seekBar, int progress,
  129. boolean fromUser) {
  130. // TODO Auto-generated method stub
  131. }
  132. @Override
  133. public void onStartTrackingTouch(SeekBar seekBar) {
  134. isChanging=true;
  135. }
  136. @Override
  137. public void onStopTrackingTouch(SeekBar seekBar) {
  138. m.seekTo(seekBar.getProgress());
  139. isChanging=false;
  140. }
  141. }
  142. }
 

Android提高21篇之一:MediaPlayer的更多相关文章

  1. Android提高21篇之二:SurfaceView的基本使用方法

    上次介绍MediaPlayer的时候稍微介绍了SurfaceView,SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,这次我就用两篇文章来介绍Su ...

  2. Android提高第二篇之SurfaceView的基本使用

    本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 上次介绍MediaPlayer的时候略微介绍了SurfaceView,SurfaceView因为能够直接从内存 ...

  3. Android提高第九篇之GridView和SQLite实现分页表格

    实现并封装一个SQL分页表格控件,不仅支持分页还是以表格的形式展示数据.先来看看本文程序运行的动画: 这个SQL分页表格控件主要分为“表格区”和“分页栏”这两部分,这两部分都是基于GridView实现 ...

  4. 【朝花夕拾】Android自定义View篇之(八)多点触控(上)MotionEvent简介

    前言 在前面的文章中,介绍了不少触摸相关的知识,但都是基于单点触控的,即一次只用一根手指.但是在实际使用App中,常常是多根手指同时操作,这就需要用到多点触控相关的知识了.多点触控是在Android2 ...

  5. 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

    前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...

  6. Android中插件开发篇之----动态加载Activity(免安装运行程序)

    一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析 ...

  7. (转) ICCV 2015:21篇最火爆研究论文

          ICCV 2015:21篇最火爆研究论文 ICCV 2015: Twenty one hottest research papers   “Geometry vs Recognition” ...

  8. android之存储篇——SQLite数据库

    转载:android之存储篇_SQLite数据库_让你彻底学会SQLite的使用 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在In ...

  9. 跟Google学习Android开发-起始篇-构建你的第一个应用程序(4)

    说明:此系列教程翻译自Google Android开发者官网的Training教程,利用Chome浏览器的自动翻译功能作初译,然后在一些语句不顺或容易造成误解的地方作局部修正.方便英文不好的开发者查看 ...

随机推荐

  1. 数据库SQL Server与C#中数据类型的对应关系

    ylbtech- .NET-Basic:数据库SQL Server与C#中数据类型的对应关系 数据库SQL SServer与C#中数据类型的对应关系 1.A,返回顶部 数据库 C#程序 int int ...

  2. Java连接Oracle10g

    1.导入驱动包: a.找到oracle安装目录下的jdbc/lib中的文件classes12.jar: b.右击你创建的JAVA工程,找到Build path,选择Add External Archi ...

  3. res/raw和assets的 区别

    res/raw和assets的相同点: 两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制. res/raw和assets的不同点: 1.res/raw中的文件会被映射到R.ja ...

  4. Tkinter教程之Grid篇

    本文转载自:http://blog.csdn.net/jcodeer/article/details/1813196 '''Tkinter教程之Grid篇'''# Tkinter参考中最推荐使用的一个 ...

  5. hdfs[命令] dfsadmin

    Usage: java DFSAdminNote: Administrative commands can only be run as the HDFS superuser. [-report] [ ...

  6. Socket.io:有点意思

    个人网站 欢迎品尝 edwardesire.com 下面页面就是使用Socket.io制作的口袋妖怪游戏(默认小屏下已隐藏,请切换到大分辨率查看).左边是游戏画面,右边是按键表和聊天室.画面达到红蓝版 ...

  7. xcode6默认不支持armv7s

    升级到xcode6以后发现,配置里关于Architectures到默认选项只有armv7和arm64.而再次之前xcode5到时代还是有armv7.armv7s和arm64三项的.  xcode5.1 ...

  8. 问题-Delphi2007编译时提示内存错误“sxs.dll. No Debug Info.ACCESS 0xXXXXX"

    相关资料:http://bbs.csdn.net/topics/340132341 问题现象:在调试程序时,未进工程文件中的TApplication.Run;证明不是代码问题. 问题原因:可能是因为* ...

  9. Linux下的JDK安装rpm命令详解

    1. 安装程序 #rpm -ivh jdk-7u79-linux-x64.rpm 出现安装协议等,按接受即可. 2.设置环境变量. #vi /etc/profile JAVA_HOME=/usr/ja ...

  10. POJ 1611 The Suspects (并查集)

    The Suspects 题目链接: http://acm.hust.edu.cn/vjudge/contest/123393#problem/B Description 严重急性呼吸系统综合症( S ...