目录

9.动画与多媒体(二)

2.播放音频与视频

2-1.使用MediaPlayer类播放音频

2-2.使用SoundPool类播放音频

2-3.使用 VideoView组件播放视频

4.难点解答

4-1.MediaPlayer 与SoundPool的区别

4-2.MediaController 的作用

9.动画与多媒体(二)

2.播放音频与视频

Android提供了对常用音频和视频格式的支持,它所支持的音频格式有MP3 ( .mp3)、3GPP(.3gp)、Ogg (.ogg)和WAVE (.wav)等,支持的视频格式有3GPP (.3gp) 和MPEG-4 (.mp4)等。通过Android API提供的相关方法,可以在Android中实现音频与视频的播放。

2-1.使用MediaPlayer类播放音频

在Android中,提供了MediaPlayer 类来播放音频。使用MediaPlayer 类播放音频比较简单,只需创建该类的对象,并为其指定要播放的音频文件,然后调用该类的start()方法播放即可。MediaPlayer中有许多方法,其中比较常用的方法及其描述如表9.6 所示。

表9.6 MediaPlayer 类中的常用方法

方法 描述
create(Context context, int resid) 根据指定的资源ID创建一个 MediaPlayer 对象
create(Context context, Uri uri) 根据指定的URI创建一个 MediaPlayer 对象
setDataSource() 指定要装载的资源
prepare() 准备播放(在播放前调用)
start() 开始播放
stop() 停止播放
pause() 暂停播放
reset() 恢复MediaPlayer到未初始化状态

下面对如何使用MediaPlayar类播放音频进行详细介绍。

1.创建MediaPlayer对象并装载音频文件

创建MediaPlayer对象并装载音频文件,可以使用MediaPlayer类提供的静态方法create()来实现,也可以通过其无参构造方法来创建并实例化该类的对象来实现。

(1)使用create()方法创建MediaPlayer对象并装载音频文件。

MediaPlayer类的静态方法create()常用的语法格式有以下两种:

◆create(Context context, int resid)

用于从资源ID所对应的资源文件中装载音频,并返回新创建的MediaPlayer对象。例如,要创建装载音频资源(res\raw\d.wav) 的MediaPlayer对象,可以使用下面的代码:

MediaPlayer player=MediaPlayer.create(this,R.raw.d);

◆create(Context context, Uri uri)

用于根据指定的URI来装载音频并返回新创建的MediaPlayer对象。例如要创建装载了音频文件(URI地址为https://www.hhh.com/sound/hhh.mp3)的MediaPlayer对象,可以使用下面的代码:

MediaPlayer player=MediaPlayer.create(this,Uri.parse("https://www.hhh.com/sound/hhh.mp3"));

注:在访问网络中的资源时,要在AndroidManifest.xml文件中授于该程序访问网络的权限,具体的授权代码如下:

<uses-permission android:name="android.permission.INTERNET"/>

(2)通过无参的构造方法来创建MediaPlayer对象并装载音频文件。

使用无参的构造方法来创建MediaPlayer对象时,需要单独指定要装载的资源,这可以使用MediaPlayer类的setDataSource()方法实现。

在使用setDataSource()方法装载音频文件后,实际上MediaPlayer并未真正装载该音频文件,还需要调用MediaPlayer的prepare()方法去真正装载音频文件。使用无参的构造方法来创建MediaPlayer对象并装载指定的音频文件,可以使用下面的代码:

MediaPlayer player1=new MediaPlayer();
try {player1.setDataSource("/sdcard/music.mp3");//指定要装载的音频文件player1.prepare();//预加载音频
}catch (I0Exception e) {e.printStackTrace();
}

注:通过MediaPlayer类的静态方法create()来创建MediaPlayer对象时,已经装载了要播放的音频,所以这种方法适用于播放单独的音频文件时。而通过无参的构造方法来创建MediaPlayer对象并装载音频文件时,可以根据需要来随时改变要加载的文件,所以这种方法适用于连续播放多个文件时。

2.开始或恢复播放

在获取到MediaPlayer对象后,就可以使用MediaPlayer类提供的start()方法来开始播放音频或恢复播放已经暂停的音频。例如,已经创建了一 个名称为“player” 的对象,并且装载了要播放的音频,可以使用下面的代码播放该音频:

player.start();//开始播放

3.停止播放

使用MediaPlayer类提供的stop()方法可以停止正在播放的音频。例如,已经创建了一个名称为“player” 的对象,并且已经开始播放装载的音频,可以使用下面的代码停止播放该音频:

player.stop();//停止播放

4.暂停播放

使用MediaPlayer类提供的pause()方法可以暂停正在播放的音频。例如,已经创建了一个名称为“player”的对象,并且已经开始播放装载的音频,可以使用下面的代码暂停播放该音频:

player.pause();//暂停播放

例:

MainActivity.java

package com.example.musicplayer;
​
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
​
import android.media.MediaParser;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.Toast;
​
import java.io.File;
import java.io.IOException;
​
public class MainActivity extends AppCompatActivity {private MediaPlayer mediaPlayer;//定义MediaPlayer对象private boolean isPause = false;//定义是否暂停private File file;//定义要播放的音频文件
​@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ActionBar actionBar=getSupportActionBar();actionBar.hide();//设置全屏显示getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//获取“播放/暂停”按钮final ImageButton btn_play=(ImageButton) findViewById(R.id.main_ib1);//获取“停止”按钮final ImageButton btn_stop=(ImageButton) findViewById(R.id.main_ib2);file=new File("/sdcard/music.mp3");//如果音频文件存在if(file.exists()){//创建MediaPlayer对象,并解析要播放的音频文件mediaPlayer=MediaPlayer.create(this, Uri.parse(file.getAbsolutePath()));}else{//提示音频文件不存在Toast.makeText(MainActivity.this, "要播放的音频文件不存在!", Toast.LENGTH_SHORT).show();return;}
​//为MediaPlayer添加完成事件监听器,实现当音频播放完毕后,重新开始播放音频mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mediaPlayer) {play();//调用play()方法,实现播放功能}});
​btn_play.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if(mediaPlayer.isPlaying() && !isPause){//暂停播放mediaPlayer.pause();isPause=true;//更换为播放图标((ImageButton) view).setImageDrawable(getResources().getDrawable(R.drawable.play,null));}else{//继续播放mediaPlayer.start();//更换为暂停图标((ImageButton) view).setImageDrawable(getResources().getDrawable(R.drawable.pause,null));isPause=false;}}});
​btn_stop.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {mediaPlayer.stop();//停止播放//更换为播放图标btn_play.setImageDrawable(getResources().getDrawable(R.drawable.play,null));}});}//音频播放private void play(){try{mediaPlayer.reset();//重置MediaPlayer对象mediaPlayer.setDataSource(file.getAbsolutePath());//重新设置要播放的音频mediaPlayer.prepare();//预加载音频mediaPlayer.start();//开始播放} catch (Exception e) {e.printStackTrace();//输出异常信息}}
​//当前Activity销毁时protected void onDestory(){if(mediaPlayer.isPlaying()){mediaPlayer.stop();}mediaPlayer.release();//释放资源super.onDestroy();}
​
}

注:要访问SD卡的文件,需要在AndroidManifest.xml文件中赋予程序访问SD卡的权限,关键代码如下:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

application节点下

android:requestLegacyExternalStorage="true"

2-2.使用SoundPool类播放音频

Android还提供了另一个播放音频的类——SoundPool (即音频池),可以同时播放多个短小的音频,而且占用的资源较少。使用SoundPool类播放音频,首先需要创建SoundPool对象,然后加载所要播放的音频,最后调用play()方法播放音频。

1.创建SoundPool对象

SoundPool类提供了一个构造方法,用来创建SoundPool对象,该构造方法的语法格式如下:

SoundPool(int maxStreams,int streamType,int srcQuality)

参数说明如下:

◆maxStreams:指定可以容纳多少个音频。

◆streamType::指定声音类型,可以通过AudioManager类提供的常量进行指定,通常使用STREAM_MUSIC。

◆srcQuality:指定音频的品质,默认值为0。

例如,创建个可以容纳 10个音频的SoundPool对象,可以使用下面的代码:

//创建一个SoundPoo1对象, 该对象可以容纳10个音频流
oundPool soundpool = new SoundPool(10,AudioManager.STREAM_SYSTEM, 0);

2.加载所要播放的音频

创建SoundPool 对象后,可以调用load()方法来加载要播放的音频。load()方法的语法格式有以下4种:

◆public int load (Context context, int resld, int priority):通过指定的资源ID来加载音频。

◆public int load (String path, int priority):通过音频文件的路径来加载音频。

◆public int load (AssetFileDescriptor afd, int priority):从AssetFileDescriptor所对应的文件中加载音频。

◆public int load (FileDescriptor fd, long offset, long length, int priority):加载FileDescriptor对象中从offset开始,长度为length的音频。

例如,要通过资源ID来加载音频文件ding.wav,可以使用下面的代码:

soundpool.load(this,R.raw.ding,1);

注:为了更好地管理所加载的每个音频,一般使用HashMap<Integer, Integer>对象来管理这些音频。这时可以先创建一个HashMap<Integer, Integer>对象,然后应用该对象的put()方法将加载的音频保存到该对象中。例如,创建一个HashMap<Integer, Integer>对象,并应用put() 方法添加一个音频,可以使用下面的代码:

//创建一个HashMap对象
HashMap<Integer,Integer> soundmap = new HashMap<Integer,Integer>();
soundmap.put(1, soundpool.load(this, R.raw.chimes, 1));

3.播放音频

调用SoundPool对象的play()方法可播放指定的音频。play() 方法的语法格式如下:

play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)

play()方法各参数的说明如表9.7 所示。

表9.7 play() 方法的参数说明

参数 描述
soundID 指定要播放的音频,该音频为通过load() 方法返回的音频
leftVolume 指定左声道的音量,取值范围为0.0~1.0
rightVolume 指定右声道的音量,取值范围为0.0~1.0
priority 指定播放音频的优先级,数值越大,优先级越高
loop 指定循环次数,0为不循环,-1 为循环
rate 指定速率,正常为1,最低为0.5, 最高为2

例如,要播放raw资源中保存的音频文件notify.wav,可以使用下面的代码:

//播放指定的音频
soundpool.play(soundpool.load(MainActivity.this,R.raw.notify, 1), 1, 1, 0, 0, 1);

例:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity">
​
​<ListViewandroid:id="@+id/main_lv1"android:layout_width="match_parent"android:layout_height="match_parent"/>
​
</RelativeLayout>

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="match_parent"android:layout_height="match_parent"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:layout_gravity="center"android:id="@+id/title"android:textSize="22sp"/>
</LinearLayout>

MainActivity.java

package com.example.selectringtone;
​
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
​
import android.media.AudioAttributes;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
​
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
​
public class MainActivity extends AppCompatActivity {
​@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ActionBar actionBar=getSupportActionBar();actionBar.hide();
​ListView listView=(ListView) findViewById(R.id.main_lv1);//获取列表视图String[] title=new String[]{"江南","关键词","爱不会绝迹","修炼爱情","那些你很冒险的梦","爱笑的眼睛","一千年以后"};//定义并初始化保存列表项文字的数组//创建一个list集合List<Map<String,Object>> listItems=new ArrayList<Map<String,Object>>();//通过for循环将列表项文字保存到Map中,并添加到List集合中for(int i=0;i<title.length;i++){Map<String,Object> map=new HashMap<String,Object>();//实例化Map对象map.put("name",title[i]);listItems.add(map);//将Map对象添加到List集合中}
​AudioAttributes attr=new AudioAttributes.Builder()//设置音效相关属性.setUsage(AudioAttributes.USAGE_GAME)//设置音效使用场景.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)//设置音效的类型.build();final SoundPool soundPool=new SoundPool.Builder()//创建SoundPool对象.setAudioAttributes(attr)//设置音效池的属性.setMaxStreams(10)//设置最多可容纳10个音频流.build();
​final HashMap<Integer,Integer> soundmap=new HashMap<Integer,Integer>();//保存要播放的音频流到HashMap对象中soundmap.put(0,soundPool.load(this,R.raw.jiangnan,1));soundmap.put(1,soundPool.load(this,R.raw.guanjianci,1));soundmap.put(2,soundPool.load(this,R.raw.aibuhuijueji,1));soundmap.put(3,soundPool.load(this,R.raw.xiulianaiqing,1));soundmap.put(4,soundPool.load(this,R.raw.naxienihenmaoxiandemeng,1));soundmap.put(5,soundPool.load(this,R.raw.aixiaodeyanjing,1));soundmap.put(6,soundPool.load(this,R.raw.yiqiannianyihou,1));
​//创建SimpleAdapter适配器SimpleAdapter adapter=new SimpleAdapter(this,listItems,R.layout.main,new String[]{"name",},new int[]{R.id.title});listView.setAdapter(adapter);//将适配器与ListView关联
​listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {//获取选项的值Map<String,Object> map=(Map<String, Object>) adapterView.getItemAtPosition(i);//播放所选音频soundPool.play(soundmap.get(i),1,1,0,0,1);}});}
}

2-3.使用 VideoView组件播放视频

在Android中提供了VideoView组件用于播放视频文件。要想使用VideoView组件播放视频,首先需要在布局文件中添加该组件, 然后在Activity 中获取该组件,并应用其setVideoPath()方法或setVideoURI()方法加载要播放的视频,最后调用start()方法来播放视频。另外,VideoView组件还提供了stop()和pause()方法,分别用于停止和暂停视频的播放。

在布局文件中添加VideoView组件的基本语法格式如下:

<VideoView属性列表>
</VideoView>

VideoView组件支持的XML属性如表9.8所示。

表9.8 VideoView 组件支持的XML 属性

XML属性 描述
android:id 设置组件的ID
android:background 设置背景,可以设置背景图片,也可以设置背景颜色
android:layout_gravity 设置对齐方式
android:layout_width 设置宽度
android:layout_height 设置高度

在Android中还提供了一个可以与VideoView组件结合使用的MediaController组件。MediaController组件用于通过图形控制界面来控制视频的播放。

例:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity">
​<VideoViewandroid:id="@+id/main_vv1"android:layout_width="match_parent"android:layout_height="match_parent"/>
</RelativeLayout>

MainActivity.java

package com.example.videoviewandmediacontroller;
​
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
​
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.view.WindowManager;
import android.widget.MediaController;
import android.widget.Toast;
import android.widget.VideoView;
​
import java.io.File;
​
public class MainActivity extends AppCompatActivity {
​@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ActionBar actionBar=getSupportActionBar();actionBar.hide();
​//设置全屏显示getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);VideoView videoView=(VideoView) findViewById(R.id.main_vv1);//指定播放模拟器SD卡上的视频文件File file=new File(Environment.getExternalStorageDirectory()+"/aishang.mp4");//创建android.widget.MediaController对象,控制视频的播放MediaController mediaController=new MediaController(MainActivity.this);
​if(file.exists()){//判断要播放的视频文件是否存在videoView.setVideoPath(file.getAbsolutePath());//指定要播放的视频videoView.setMediaController(mediaController);//设置VideoView与MediaController相关联videoView.requestFocus();//让VideoView获得焦点try {videoView.start();//开始播放视频} catch (Exception e) {e.printStackTrace();//输出异常信息}//为VideoView添加完成事件监听器,实现视频播放结束后的提示信息videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mediaPlayer) {//弹出消息提示框显示播放完毕Toast.makeText(MainActivity.this, "视频播放完毕!", Toast.LENGTH_SHORT).show();}});}else {//弹出消息提示框提示文件不存在Toast.makeText(MainActivity.this,"要播放的视频文件不存在", Toast.LENGTH_SHORT).show();}}
}

AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"tools:ignore="ProtectedPermissions" />

AndroidManifest.xml的application节点下:

android:requestLegacyExternalStorage="true"

4.难点解答

4-1.MediaPlayer 与SoundPool的区别

使用MediaPlayer每次只能播放一-个音频,适用于播放长音乐或是背景音乐;使用SoundPool可以同时播放多个短小的音频,而且占用的资源较少,适用于播放按键音或者消息提示音等。

4-2.MediaController 的作用

MediaController是一个与MediaPlayer相匹配的Android控件,它主要集合了媒体播放器的控制功能,用于控制MediaPlayer播放状态的同步。通常包含“播放/暂停”“后退”“快进”和进度滑块等按钮。实例化此类后,MediaController 将创建一组默认的控件, 并且浮动在界面的最上层。如果空闲3秒钟,窗口将消失,当用户触摸锚定视图时,窗口将重新出现。

9.Android学习之动画与多媒体(二)相关推荐

  1. Android学习笔记--动画特效

    直接上代码,有事先不多写,以后在补 MainActivity 1 package com.wuxianedu.animation; 2 3 import android.support.annotat ...

  2. Android实用技巧.动画效果(二)

    LayoutAnimationController实现子布局进入动画效果 以listView为例设置item进入动画: 首先设置list界面 <?xml version="1.0&qu ...

  3. android学习笔记之多线程(二)

    这个需要在输出,点击start后会隔一会输出一行字,点end会结束输出. Code package tk.handleractivity;import android.app.Activity; im ...

  4. 二、Android动画学习---属性动画

    目录 八.Property Animation(属性动画)ValueAnimator基本使用 (一) 概述 1.为什么引入Property Animator(属性动画) (二)  ValueAnima ...

  5. Android学习之登陆界面设计(二)基本界面设计

    Android学习之登陆界面设计(二)基本界面设计 前提 绘图样式 - drawable bg_login_btn_submit.xml bg_login_panel_slide.xml bg_log ...

  6. Android学习-运用手机多媒体-通知使用技巧、调用摄像头拍照、从相册中选取照片、播放音频和视频文件(MediaPlayer、VideoView)

    android提供了一系列的API,使得我们可以在程序中调用很多的多媒体资源,从而编写出更加丰富多彩的应用程序. 使用通知 通知(Notification)是Android系统中比较有特色的一个功能, ...

  7. dagger android 学习(二):AndroidInjector的使用

    本系列博客主要用于自己学习积累,顺便帮助新手入门,如有问题,多多包涵.更详细的一些使用可以看看其他更加详细的博客. dagger android 学习(一):dagger基础使用 dagger and ...

  8. 【转】 Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner

    目录(?)[-] GridView Spinner GridView GridView是网格状布局,如图所示.在了解ListView后,很容易了解GridView.下面是例子的XML文件. <? ...

  9. android学习笔记---55_frame动画的实现,Java技术qq交流群:JavaDream:251572072

    android学习笔记---55_frame动画的实现,Java技术qq交流群:JavaDream:251572072 Java技术qq交流群:JavaDream:251572072 2013/5/1 ...

最新文章

  1. 毕业三年薪水翻三倍!?你想要吗?
  2. 【PAT乙级】 1010 一元多项式求导 (25 分)
  3. 修改mysql的my.ini文件,导致mysql服务1067启动失败的解决方法
  4. Linux 安装USB摄像头
  5. php asp 语法,ASP 语法
  6. getParameterValues用法
  7. java 读取txt字符串_java读取txt并获取某一部分字符串
  8. python中文字体下载_python中matlabplot和seaborn中文字体显示的一种解决方案
  9. Android异常总结--- java.net.SocketTimeoutException: Transport endpoint is not connected
  10. matlab计算macd_[原创]基于MATLAB的一个简单的交易策略(基于MACD)的Matlab代码
  11. IDE安装与配置(2018)
  12. 用SPSS做正态分布检验
  13. SPSS的中分层聚类法的实际应用详解
  14. 目标检测(Object Detection)
  15. Linux虚拟机网络配置
  16. English Study
  17. SLCP验厂辅导,工厂进行社会劳工整合项目(SLCP认证)验证的具体步骤是
  18. JAVA JMS 简介
  19. Win10使用FTP实现手机访问电脑FTP服务
  20. centos离线配置yun源

热门文章

  1. Linux单双引号嵌套引发的小问题
  2. 这几大挣钱方式,你能学会哪一种?
  3. PCIe各版本结构剖析
  4. 通过u盘启动计算机使用ghost安装系统步骤,如何用u盘装ghost win7系统步骤
  5. 计算机网络课程设计网络嗅探器
  6. Java面试题:关于sleep()和write()的简答题
  7. Rosetta stone
  8. Rosetta Stone罗塞塔:Fatal Application Error #1141
  9. OTT供应商揭示安全如何影响观众体验
  10. css做个波浪悬浮球?