android中常见声音操作方式(Ringtone,SoundPool,MediaPlayer)小结 android中常见声音操作方式(Ringtone,SoundPool,MediaPlayer)小结

android中常见声音操作方式(Ringtone,SoundPool,MediaPlayer)小结

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

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

注意: 
关于这三个类的介绍我全部用的是android 自身的java doc描述; 
全部摘自于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 {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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 {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

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{}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155

下面是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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

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

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

注意: 
关于这三个类的介绍我全部用的是android 自身的java doc描述; 
全部摘自于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 {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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 {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

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{}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155

下面是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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

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

猜你喜欢

转载自blog.csdn.net/jhope/article/details/81018312