Android开发中有时候需要用到播放声音操作,在android API 的media包中有三种方式可供我们选择,它们分别是Ringtone,SoundPool,MediaPlayer。因为在我目前的项目中暂时用不到播放很长的音频文件,只需要播放一些简短的提示音,所以在这篇博文中我只是简单的记录下。

  • 1.Ringtone.java
  • 2.SoundPool.java
  • 3.MediaPlayer.java
  • 4.demo
  • 5.bug record

注意:
关于这三个类的介绍我全部用的是android 自身的Javadoc描述;
全部摘自于android-23;
因为我的项目中主要用到Ringtone,所以展示了它全部的描述;

1.Ringtone.java

关于Ringtone的介绍。

package android.media;
/**
* Ringtone provides a quick method for playing a ringtone, notification, or
* other similar types of sounds.
* <p>
* For ways of retrieving {@link Ringtone} objects or to show a ringtone
* picker, see {@link RingtoneManager}.
*
* @see RingtoneManager
*/
public class Ringtone {}

2.SoundPool.java

关于SoundPool的介绍。

/**
* The SoundPool class manages and plays audio resources for applications.
*
* <p>A SoundPool is a collection of samples that can be loaded into memory
* from a resource inside the APK or from a file in the file system. The
* SoundPool library uses the MediaPlayer service to decode the audio
* into a raw 16-bit PCM mono or stereo stream. This allows applications
* to ship with compressed streams without having to suffer the CPU load
* and latency of decompressing during playback.</p>
*
* <p>In addition to low-latency playback, SoundPool can also manage the number
* of audio streams being rendered at once. When the SoundPool object is
* constructed, the maxStreams parameter sets the maximum number of streams
* that can be played at a time from this single SoundPool. SoundPool tracks
* the number of active streams. If the maximum number of streams is exceeded,
* SoundPool will automatically stop a previously playing stream based first
* on priority and then by age within that priority. Limiting the maximum
* number of streams helps to cap CPU loading and reducing the likelihood that
* audio mixing will impact visuals or UI performance.</p>
*
* <p>Sounds can be looped by setting a non-zero loop value. A value of -1
* causes the sound to loop forever. In this case, the application must
* explicitly call the stop() function to stop the sound. Any other non-zero
* value will cause the sound to repeat the specified number of times, e.g.
* a value of 3 causes the sound to play a total of 4 times.</p>
*
* <p>The playback rate can also be changed. A playback rate of 1.0 causes
* the sound to play at its original frequency (resampled, if necessary,
* to the hardware output frequency). A playback rate of 2.0 causes the
* sound to play at twice its original frequency, and a playback rate of
* 0.5 causes it to play at half its original frequency. The playback
* rate range is 0.5 to 2.0.</p>
*
* <p>Priority runs low to high, i.e. higher numbers are higher priority.
* Priority is used when a call to play() would cause the number of active
* streams to exceed the value established by the maxStreams parameter when
* the SoundPool was created. In this case, the stream allocator will stop
* the lowest priority stream. If there are multiple streams with the same
* low priority, it will choose the oldest stream to stop. In the case
* where the priority of the new stream is lower than all the active
* streams, the new sound will not play and the play() function will return
* a streamID of zero.</p>
*
* <p>Let's examine a typical use case: A game consists of several levels of
* play. For each level, there is a set of unique sounds that are used only
* by that level. In this case, the game logic should create a new SoundPool
* object when the first level is loaded. The level data itself might contain
* the list of sounds to be used by this level. The loading logic iterates
* through the list of sounds calling the appropriate SoundPool.load()
* function. This should typically be done early in the process to allow time
* for decompressing the audio to raw PCM format before they are needed for
* playback.</p>
*
* <p>Once the sounds are loaded and play has started, the application can
* trigger sounds by calling SoundPool.play(). Playing streams can be
* paused or resumed, and the application can also alter the pitch by
* adjusting the playback rate in real-time for doppler or synthesis
* effects.</p>
*
* <p>Note that since streams can be stopped due to resource constraints, the
* streamID is a reference to a particular instance of a stream. If the stream
* is stopped to allow a higher priority stream to play, the stream is no
* longer be valid. However, the application is allowed to call methods on
* the streamID without error. This may help simplify program logic since
* the application need not concern itself with the stream lifecycle.</p>
*
* <p>In our example, when the player has completed the level, the game
* logic should call SoundPool.release() to release all the native resources
* in use and then set the SoundPool reference to null. If the player starts
* another level, a new SoundPool is created, sounds are loaded, and play
* resumes.</p>
*/
public class SoundPool {}

3.MediaPlayer.java

package android.media;
/**
* MediaPlayer class can be used to control playback
* of audio/video files and streams. An example on how to use the methods in
* this class can be found in {@link android.widget.VideoView}.
* For ways of retrieving {@link Ringtone} objects or to show a ringtone
* picker, see {@link RingtoneManager}.
*
* @see RingtoneManager
*/
public class MediaPlayer implements SubtitleController.Listener{}

4.demo

因为这个demo很简单,就一个Activity和xml,所以我就不提供源码下载了。
请直接看码:

package android.media;
package org.tuzhao.demo.activity; import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View; import org.tuzhao.sqlite.R; import java.io.IOException; /**
* three types to play sound
* @author tuzhao
*/
public class SoundActivity extends AppCompatActivity implements View.OnClickListener { private Ringtone ringtone; private SoundPool soundPool;
private int loadId; private MediaPlayer mediaPlayer; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sound);
//初始化这三个方法
ringtone = initRingtone(this); soundPool = initSoundPool();
loadId = soundPool.load(this, R.raw.beep, 1); mediaPlayer = initMediaPlayer(this, 0); findViewById(R.id.bt_ringtone).setOnClickListener(this);
findViewById(R.id.bt_sound_pool).setOnClickListener(this);
findViewById(R.id.bt_media).setOnClickListener(this);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_ringtone:
ringtone.play();
break;
case R.id.bt_sound_pool:
soundPool.play(loadId, 1.0f, 1.0f, 0, 0, 1.0f);
break;
case R.id.bt_media:
mediaPlayer.start();
break;
}
} @Override
protected void onDestroy() {
super.onDestroy();
//release resource of this two types.
soundPool.release();
mediaPlayer.release();
} /**
* init type of Ringtone
* @param context Activity
* @return Ringtone
*/
private Ringtone initRingtone(Activity context) {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
return RingtoneManager.getRingtone(context, notification);
} /**
* init type of SoundPool
* @return SoundPool
*/
@SuppressWarnings("deprecation")
private SoundPool initSoundPool() { // The content of the comments need API-23
// SoundPool.Builder builder=new SoundPool.Builder();
// builder.setMaxStreams(10);
//
// AudioAttributes.Builder audioBuilder=new AudioAttributes.Builder();
// audioBuilder.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN);
// audioBuilder.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED);
// audioBuilder.setLegacyStreamType(AudioManager.STREAM_SYSTEM);
// audioBuilder.setUsage(AudioAttributes.USAGE_NOTIFICATION);
// AudioAttributes attributes = audioBuilder.build();
//
// builder.setAudioAttributes(attributes);
// SoundPool soundPool = builder.build();
return new SoundPool(10, AudioManager.STREAM_NOTIFICATION, 5);
} /**
* init type of MediaPlayer
* @param context Activity
* @param rawId the id of raw
* @return MediaPlayer
*/
public MediaPlayer initMediaPlayer(Activity context, int rawId) {
context.setVolumeControlStream(AudioManager.STREAM_MUSIC);
final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
/**
* When the beep has finished playing, rewind to queue up another one.
*/
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.seekTo(0);
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mediaPlayer.release();
return true;
}
});
AssetFileDescriptor file;
if (rawId == 0) {
file = context.getResources().openRawResourceFd(R.raw.beep);
} else {
file = context.getResources().openRawResourceFd(rawId);
}
try {
mediaPlayer.setDataSource(file.getFileDescriptor(),
file.getStartOffset(), file.getLength());
file.close();
float BEEP_VOLUME = 1.0f;
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
Log.i("initSpecifiedSound", "what happened to init sound? you need to deal it .");
return null;
}
return mediaPlayer;
} }

下面是xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.tuzhao.sqlite.activity.SoundActivity"> <Button
android:id="@+id/bt_ringtone"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="88dp"
android:text="Ringtone"
android:textAllCaps="false"
/> <Button
android:id="@+id/bt_sound_pool"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/bt_ringtone"
android:layout_alignStart="@+id/bt_ringtone"
android:layout_below="@+id/bt_ringtone"
android:layout_marginTop="15dp"
android:text="SoundPool"
android:textAllCaps="false"/> <Button
android:id="@+id/bt_media"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/bt_sound_pool"
android:layout_alignStart="@+id/bt_sound_pool"
android:layout_below="@+id/bt_sound_pool"
android:layout_marginTop="15dp"
android:text="MediaPlayer"
android:textAllCaps="false"/>
</RelativeLayout>

5.bug record

bugs:
AudioTrack: AudioFlinger could not create track, status: -12
AudioFlinger: no more track names available
AudioSink: Unable to create audio track
MediaPlayer: Should have subtitle controller already set

resolve:我出现这种情况是因为我最刚开始采用的不是上面Java文件初始化的方法,而是每播放一次声音就new 一个对象来播放声音。这样能播放,但是播放了十几次就报上面的错误。正确做法是只初始化一次。
每次调用下面这三个分别对应方法:
soundPool.play(sourceId, 1.0f, 1.0f, 0, 0, 1.0f);
ringtone.play();
mediaPlayer.start();


本人才疏学浅,出错在所难免。如文中有错误的地方望指正,谢谢!
欢迎关注我的Github账号:https://github.com/tuzhao

android中常见声音操作方式(Ringtone,SoundPool,MediaPlayer)小结的更多相关文章

  1. Android中常见的内存泄漏

    为什么会产生内存泄漏? 当一个对象已经不需要再使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏. ...

  2. Android 中常见控件的介绍和使用

    1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.la ...

  3. Android中常见的MVC模式

    MVC模式的简要介绍 MVC是三个单词的缩写,分别为: 模型(Model),视图(View)和控制Controller). MVC模式的目的就是实现Web系统的职能分工. Model层实现系统中的业务 ...

  4. (转载)Android开发——Android中常见的4种线程池(保证你能看懂并理解)

    0.前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337 使用线程池可以给我们带来很多好处,首先通过线程池中线程的重用 ...

  5. Android开发——Android中常见的4种线程池(保证你能看懂并理解)

    0.前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52415337 使用线程池可以给我们带来很多好处,首先通过线程池中线程的重用 ...

  6. android中常见的Drawable资源有哪些?

    Drawable资源是安卓应用中最常见的一种资源,比如图片等,因此,对于初学者而言,必须掌握drawable资源相关应用. 今天在网上刚好看到了一篇介绍android Drawable资源的文章,分享 ...

  7. Android中常见功能包描述(转)

    在Android中,各种包写成android.*的方式,重要包的描述如下所示:android.app :提供高层的程序模型.提供基本的运行环境android.content:包含各种的对设备上的数据进 ...

  8. Android中常见功能包描述

    在Android中,各种包写成android.*的方式,重要包的描述如下所示:android.app :提供高层的程序模型.提供基本的运行环境android.content:包含各种的对设备上的数据进 ...

  9. android中常见的设计模式有哪些?

    建造者模式 建造者模式最明显的标志就是Build类,而在Android中最常用的就是Dialog的构建,Notification的构建也是标准的建造者模式. 建造者模式很好理解,如果一个类的构造需要很 ...

随机推荐

  1. 总结C#保留小数位数

    2.C#保留小数位N位,四舍五入 . decimal d= decimal.Round(decimal.Parse("0.55555"),2); 3.C#保留小数位N位四舍五入 M ...

  2. 通过域 组策略禁用U盘(只允许部份许可U盘可在客户端读取)

    U盘禁用设置步骤: 1.客户端 注册表修改,USBStor  的start改为4 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\UsbSto ...

  3. Python环境搭建—安利Python小白的Python安装详细教程

    人生苦短,我用Python.众所周知,Python目前越来越火,学习Python的小伙伴也越来越多.最近看到群里的小伙伴经常碰到不会安装Python或者不知道去哪下载Python安装包等系列问题,为了 ...

  4. JavaScript笔记(6)

    一.Date Date实例用来处理日期和时间.Date对象基于1970年1月1日(格林威治时间)世界标准时间起经过的毫秒数.常用:new Date();new Date(value);new Date ...

  5. 关于vs2012/2013的C编译器生成的exe的向后兼容xp的问题

    问题一:编译出来的exe在xp上面运行提示"不是有效的win32应用程序" 在vs2012/2013版本里面,其自带的c编译器cl.exe,若直接使用cl a.c编译,那么生成出来 ...

  6. Word中查找替换软回车键和回车键

    在Word中使用搜索功能搜索“^p”组合字符串可以查找文档中的所有换行符(回车键),使用“^l”(英文输入状态下shift+6与小写字符L的组合)可以搜索所有的软回车符.使用替换功能就可以搜索替换二者 ...

  7. Mysql学习总结(11)——MySql存储过程与函数

    摘要:存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存储过程和函数是在 ...

  8. 与TCP/IP协议的初次见面(一)

    与TCP/IP协议的初次见面(一) 前言 今下午刚才女朋友那边回来,唉,算是情人节去找她吧,穷屌丝住不起好酒店,住的打折酒店,只是女朋友来姨妈了,万幸啊,牙还疼得不行,这几天光照应她了,没空写博客了. ...

  9. KETTLE使用javascript步骤过滤特殊字符

    KETTLE使用javascript步骤过滤特殊字符 使用kettle在抽取大量excel数据时.总是遇到excel中有一些特殊字符,导致ExecuteSQL script步骤运行失败,本文记录一些方 ...

  10. Tools-->SQL Server Profiler监视数据库

    http://www.cnblogs.com/lorking/p/4062787.html https://docs.microsoft.com/en-us/sql/tools/sql-server- ...