9.Android学习之动画与多媒体(二)
目录
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学习之动画与多媒体(二)相关推荐
- Android学习笔记--动画特效
直接上代码,有事先不多写,以后在补 MainActivity 1 package com.wuxianedu.animation; 2 3 import android.support.annotat ...
- Android实用技巧.动画效果(二)
LayoutAnimationController实现子布局进入动画效果 以listView为例设置item进入动画: 首先设置list界面 <?xml version="1.0&qu ...
- android学习笔记之多线程(二)
这个需要在输出,点击start后会隔一会输出一行字,点end会结束输出. Code package tk.handleractivity;import android.app.Activity; im ...
- 二、Android动画学习---属性动画
目录 八.Property Animation(属性动画)ValueAnimator基本使用 (一) 概述 1.为什么引入Property Animator(属性动画) (二) ValueAnima ...
- Android学习之登陆界面设计(二)基本界面设计
Android学习之登陆界面设计(二)基本界面设计 前提 绘图样式 - drawable bg_login_btn_submit.xml bg_login_panel_slide.xml bg_log ...
- Android学习-运用手机多媒体-通知使用技巧、调用摄像头拍照、从相册中选取照片、播放音频和视频文件(MediaPlayer、VideoView)
android提供了一系列的API,使得我们可以在程序中调用很多的多媒体资源,从而编写出更加丰富多彩的应用程序. 使用通知 通知(Notification)是Android系统中比较有特色的一个功能, ...
- dagger android 学习(二):AndroidInjector的使用
本系列博客主要用于自己学习积累,顺便帮助新手入门,如有问题,多多包涵.更详细的一些使用可以看看其他更加详细的博客. dagger android 学习(一):dagger基础使用 dagger and ...
- 【转】 Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner
目录(?)[-] GridView Spinner GridView GridView是网格状布局,如图所示.在了解ListView后,很容易了解GridView.下面是例子的XML文件. <? ...
- android学习笔记---55_frame动画的实现,Java技术qq交流群:JavaDream:251572072
android学习笔记---55_frame动画的实现,Java技术qq交流群:JavaDream:251572072 Java技术qq交流群:JavaDream:251572072 2013/5/1 ...
最新文章
- 毕业三年薪水翻三倍!?你想要吗?
- 【PAT乙级】 1010 一元多项式求导 (25 分)
- 修改mysql的my.ini文件,导致mysql服务1067启动失败的解决方法
- Linux 安装USB摄像头
- php asp 语法,ASP 语法
- getParameterValues用法
- java 读取txt字符串_java读取txt并获取某一部分字符串
- python中文字体下载_python中matlabplot和seaborn中文字体显示的一种解决方案
- Android异常总结--- java.net.SocketTimeoutException: Transport endpoint is not connected
- matlab计算macd_[原创]基于MATLAB的一个简单的交易策略(基于MACD)的Matlab代码
- IDE安装与配置(2018)
- 用SPSS做正态分布检验
- SPSS的中分层聚类法的实际应用详解
- 目标检测(Object Detection)
- Linux虚拟机网络配置
- English Study
- SLCP验厂辅导,工厂进行社会劳工整合项目(SLCP认证)验证的具体步骤是
- JAVA JMS 简介
- Win10使用FTP实现手机访问电脑FTP服务
- centos离线配置yun源