实战第11篇:MediaPlayer实现森林协奏曲

381 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情


本次实战森林协奏曲app,点击动物头像可发出对应的叫声,可用于哄娃。 image3.png

一、知识储备

本期讲Android的多媒体之音频播放,音频播放比较简单,主要涉及一个类,那就是MediaPlayer

1.1 多媒体播放器 MediaPlayer

MediaPlayerAndroid中处理多媒体播放的类,它可以播放音频,也可以播放视频,但是播放视频需要搭配一个幕布,也就是视频展示的View。播放音频就不用,可以直接调用。

因此,从这里可以看出,MediaPlayer只负责数据流的处理,并不负责界面的展示,它是一个幕后工作者,并不是一个我们理解的那个播放器产品。

9ac170a34bf64fe4d7026db3883739d6.jpeg

所以啊,并不是xml中定义一下<MediaPlayer>就出来了,我们得通过调用MediaPlayer写代码,才能搞出来上面那种播放器。

1.2 音频的加载和播放

要想播放音频,首先得构建一个MediaPlayer对象,然后加载音频文件。

MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource("...");
mediaPlayer.prepare();
mediaPlayer.start();

setDataSource()设置音频的数据源,可以是音频文件,也可以是音频网址,如果是播放网络音频的话,那就是这样设置setDataSource("http://juejin.cn/ok.mp3")

prepare()是准备方法,做一些文件的预加载和缓冲工作,最后调用start()进行播放。

上面3个方法有先后顺序要求。

1.3 其他常用方法

除此之外,MediaPlayer还有很多其他常用的方法,经过我的转化如下表所示。

方法作用
void prepare()同步准备
void start()开始播放
void pause()暂停
void stop()停止播放
void seekTo(int msec)指定播放位置(以毫秒为单位),相当于拖动进度条到某个时间点
int getCurrentPosition()得到当前播放位置(ms),相当于进度条当前的位置
int getDuration()得到文件的时间(ms),相当于音频的总时长

二、实战过程

我们再来回顾一下,要做的功能:

image3.png

大体理一下思路:

  • 首先画页面。把5个小动物(我们用ImageView控件)分别放到5个方向。
  • 然后设事件。分别给它们设置点击事件,就是点击要触发的操作。
  • 最后播文件。当被点击时,调用MediaPlayer播放对应小动物的音频文件。

2.1 准备资源

巧妇难为无米之炊,巧程序员也一样,首先准备素材啊,小动物的图片和叫声的资源如何分布。

image.png

看上图,我们主要关心4个地方,逻辑代码和布局代码,这个不用多说了。

其中图片文件放到mipmap中,音频文件放到raw中,这是Android体系中约定的规范。

2.2 代码实现

五个小动物的排列布局activity_main.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<ConstraintLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/bird"
        android:onClick="bird"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/cat"
        android:onClick="cat"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/dog"
        android:onClick="dog" />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/forg"
        android:onClick="forg"/>
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/sheep"
        android:onClick="sheep"/>
</ConstraintLayout>

受限于篇幅,代码省略了部分细节,重点关注android:onClick="xxx",代表调用MainActivity中对应的点击事件。

很快,MainActivity就来了。

public class MainActivity extends Activity {

    MediaPlayer bird;
    MediaPlayer cat;
    MediaPlayer dog;
    MediaPlayer forg;
    MediaPlayer sheep;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bird = MediaPlayer.create(this, R.raw.bird);
        cat = MediaPlayer.create(this, R.raw.cat);
        dog = MediaPlayer.create(this, R.raw.dog);
        forg = MediaPlayer.create(this, R.raw.forg);
        sheep = MediaPlayer.create(this, R.raw.sheep);
    }

    public void bird(View view) {
        bird.start();
    }

    public void cat(View view) {
        cat.start();
    }

    public void dog(View view) {
        dog.start();
    }

    public void forg(View view) {
        forg.start();
    }

    public void sheep(View view) {
        sheep.start();
    }
}

我们看到代码中,怎么和知识点里讲的不一样。没有new对象,也没有调用setDataSource("...")

是的,MediaPlayer的构建方式是多种多样的,也可以通过create(this, [raw下文件])一次性创建并加载。

MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.sound_music);
mediaPlayer.prepare();
mediaPlayer.start();

好了,Run一下程序,可以拿着这个App去哄孩子了。

三、最后

我是TF男孩,关注专栏Android入门教程《Java转Android》。每天800字,30天入门安卓开发。

本专辑掘金社区独家发布,转载请注明出处,如读者在其他平台发现,属被盗用,请告知。