Android提高21篇之一:MediaPlayer
本文介绍MediaPlayer的使用。MediaPlayer可以播放音频和视频,另外也可以通过VideoView来播放视频,虽然VideoView比MediaPlayer简单易用,但定制性不如用MediaPlayer,要视情况选择了。MediaPlayer播放音频比较简单,但是要播放视频就需要SurfaceView。SurfaceView比普通的自定义View更有绘图上的优势,它支持完全的OpenGL ES库。
先贴出本文程序运行结果的截图,上面是播放/停止音频,可用SeekBar来调进度,下面是播放/停止视频,也是用SeekBar来调进度:

main.xml的源码:
- <linearlayout android:id="@+id/LinearLayout01"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical">
- <seekbar android:id="@+id/SeekBar01" android:layout_height="wrap_content"
- android:layout_width="fill_parent">
- <linearlayout android:id="@+id/LinearLayout02"
- android:layout_width="wrap_content" android:layout_height="wrap_content">
- <button android:id="@+id/Button01" android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:text="播放音频">
- <button android:id="@+id/Button02" android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:text="停止播放">
- <seekbar android:id="@+id/SeekBar02" android:layout_height="wrap_content"
- android:layout_width="fill_parent">
- <surfaceview android:id="@+id/SurfaceView01"
- android:layout_width="fill_parent" android:layout_height="250px">
- <linearlayout android:id="@+id/LinearLayout02"
- android:layout_width="wrap_content" android:layout_height="wrap_content">
- <button android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:id="@+id/Button03"
- android:text="播放视频">
- <button android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:text="停止播放" android:id="@+id/Button04">
本文程序的源码,有点长:
- package com.testMedia;
- import java.io.IOException;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.app.Activity;
- import android.media.AudioManager;
- import android.media.MediaPlayer;
- import android.os.Bundle;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.view.View;
- import android.widget.Button;
- import android.widget.SeekBar;
- import android.widget.Toast;
- public class testMedia extends Activity {
- /** Called when the activity is first created. */
- private SeekBar skb_audio=null;
- private Button btn_start_audio = null;
- private Button btn_stop_audio = null;
- private SeekBar skb_video=null;
- private Button btn_start_video = null;
- private Button btn_stop_video = null;
- private SurfaceView surfaceView;
- private SurfaceHolder surfaceHolder;
- private MediaPlayer m = null;
- private Timer mTimer;
- private TimerTask mTimerTask;
- private boolean isChanging=false;//互斥变量,防止定时器与SeekBar拖动时进度冲突
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //----------Media控件设置---------//
- m=new MediaPlayer();
- //播放结束之后弹出提示
- m.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
- @Override
- public void onCompletion(MediaPlayer arg0) {
- Toast.makeText(testMedia.this, "结束", 1000).show();
- m.release();
- }
- });
- //----------定时器记录播放进度---------//
- mTimer = new Timer();
- mTimerTask = new TimerTask() {
- @Override
- public void run() {
- if(isChanging==true)
- return;
- if(m.getVideoHeight()==0)
- skb_audio.setProgress(m.getCurrentPosition());
- else
- skb_video.setProgress(m.getCurrentPosition());
- }
- };
- mTimer.schedule(mTimerTask, 0, 10);
- btn_start_audio = (Button) this.findViewById(R.id.Button01);
- btn_stop_audio = (Button) this.findViewById(R.id.Button02);
- btn_start_audio.setOnClickListener(new ClickEvent());
- btn_stop_audio.setOnClickListener(new ClickEvent());
- skb_audio=(SeekBar)this.findViewById(R.id.SeekBar01);
- skb_audio.setOnSeekBarChangeListener(new SeekBarChangeEvent());
- btn_start_video = (Button) this.findViewById(R.id.Button03);
- btn_stop_video = (Button) this.findViewById(R.id.Button04);
- btn_start_video.setOnClickListener(new ClickEvent());
- btn_stop_video.setOnClickListener(new ClickEvent());
- skb_video=(SeekBar)this.findViewById(R.id.SeekBar02);
- skb_video.setOnSeekBarChangeListener(new SeekBarChangeEvent());
- surfaceView = (SurfaceView) findViewById(R.id.SurfaceView01);
- surfaceHolder = surfaceView.getHolder();
- surfaceHolder.setFixedSize(100, 100);
- surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
- }
- /*
- * 按键事件处理
- */
- class ClickEvent implements View.OnClickListener{
- @Override
- public void onClick(View v) {
- if(v==btn_start_audio)
- {
- m.reset();//恢复到未初始化的状态
- m=MediaPlayer.create(testMedia.this, R.raw.big);//读取音频
- skb_audio.setMax(m.getDuration());//设置SeekBar的长度
- try {
- m.prepare(); //准备
- } catch (IllegalStateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- m.start(); //播放
- }
- else if(v==btn_stop_audio || v==btn_stop_video)
- {
- m.stop();
- }
- else if(v==btn_start_video)
- {
- m.reset();//恢复到未初始化的状态
- m=MediaPlayer.create(testMedia.this, R.raw.test);//读取视频
- skb_video.setMax(m.getDuration());//设置SeekBar的长度
- m.setAudioStreamType(AudioManager.STREAM_MUSIC);
- m.setDisplay(surfaceHolder);//设置屏幕
- try {
- m.prepare();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalStateException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- m.start();
- }
- }
- }
- /*
- * SeekBar进度改变事件
- */
- class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener{
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress,
- boolean fromUser) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- isChanging=true;
- }
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- m.seekTo(seekBar.getProgress());
- isChanging=false;
- }
- }
- }
Android提高21篇之一:MediaPlayer的更多相关文章
- Android提高21篇之二:SurfaceView的基本使用方法
上次介绍MediaPlayer的时候稍微介绍了SurfaceView,SurfaceView由于可以直接从内存或者DMA等硬件接口取得图像数据,因此是个非常重要的绘图容器,这次我就用两篇文章来介绍Su ...
- Android提高第二篇之SurfaceView的基本使用
本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处! 上次介绍MediaPlayer的时候略微介绍了SurfaceView,SurfaceView因为能够直接从内存 ...
- Android提高第九篇之GridView和SQLite实现分页表格
实现并封装一个SQL分页表格控件,不仅支持分页还是以表格的形式展示数据.先来看看本文程序运行的动画: 这个SQL分页表格控件主要分为“表格区”和“分页栏”这两部分,这两部分都是基于GridView实现 ...
- 【朝花夕拾】Android自定义View篇之(八)多点触控(上)MotionEvent简介
前言 在前面的文章中,介绍了不少触摸相关的知识,但都是基于单点触控的,即一次只用一根手指.但是在实际使用App中,常常是多根手指同时操作,这就需要用到多点触控相关的知识了.多点触控是在Android2 ...
- 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象
前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...
- Android中插件开发篇之----动态加载Activity(免安装运行程序)
一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析 ...
- (转) ICCV 2015:21篇最火爆研究论文
ICCV 2015:21篇最火爆研究论文 ICCV 2015: Twenty one hottest research papers “Geometry vs Recognition” ...
- android之存储篇——SQLite数据库
转载:android之存储篇_SQLite数据库_让你彻底学会SQLite的使用 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在In ...
- 跟Google学习Android开发-起始篇-构建你的第一个应用程序(4)
说明:此系列教程翻译自Google Android开发者官网的Training教程,利用Chome浏览器的自动翻译功能作初译,然后在一些语句不顺或容易造成误解的地方作局部修正.方便英文不好的开发者查看 ...
随机推荐
- C++ STL算法系列3---求和:accumulate
该算法在numeric头文件中定义. 假设vec是一个int型的vector对象,下面的代码: //sum the elements in vec starting the summation wit ...
- 使用SQL语句清空数据库所有表的数据
使用SQL语句清空数据库所有表的数据 近来发现数据库过大,空间不足,因此打算将数据库的数据进行全面的清理,但表非常多,一张一张的清空,实在麻烦,因此就想利用SQL语句一次清空所有数据.找到了三种方法进 ...
- [OFBiz]开发 二
1.svn中check出的apache-ofbiz-10.04(svn_2010-04-01代码备分)由于它的所有文件都不含有中文,所以Eclipse使用什么编码方式都可以(ISO, GBK, UTF ...
- 《Python核心编程》 第十章 错误和异常
10–1. 引发异常. 以下的哪个因素会在程序执行时引发异常? 注意这里我们问的并不是异常的原因. a) 用户 b) 解释器 c) 程序 d) 以上所有 e) 只有 b) 和 c) f) 只有 a) ...
- duilib relativepos属性导致控件错误的bug修复
转载请说明出处,谢谢~~ 我在仿酷狗音乐播放器的开发日志系列里,曾经提到了这个bug,文章地址为:http://blog.csdn.net/zhuhongshu/article/details/381 ...
- Dubbo服务重载方法在JDK1.8上调用出错的问题(待解决)
据说是javassist版本太低不支持JDK1.8,但是测试升级了还是调用出错.预留,待解决.
- oracle修改密码及账户锁定
在oracle修改密码的时候,一种是用dba账户来修改用户的密码,一种是用户自己修改自己的密码: SQL> alter user kel identified by kel; 解锁命令: SQL ...
- bzoj 1537 [POI2005]Aut- The Bus(DP+BIT)
[题意] 顺序经过k个点,求获得的最大权值和. [思路] 设f[i]表示到第i个点,则有转移式: f[i]=min{ f[j]+w[i] } x[j]<=x[i],y[j]<=y[i] 满 ...
- c++ 概念及学习/c++ concept&learning(三)
这一篇继续说说程序设计中的基本语句:控制块 一 if类控制语句 if if else if , else if ,else if(条件语句){如果条件为真,要做的一些事情} if(条件语句) {如 ...
- java BigInteger类的用法
import java.math.BigInteger; Scanner in = new Scanner(System.in); BigInteger x1 = new BigInteger(&qu ...