问题描述
在Android 2.2+有叫什么SoundPool.OnLoadCompleteListener让知道一个声音是否已经被成功加载与否。
On Android 2.2+ there is something called SoundPool.OnLoadCompleteListener allowing to know whether a sound has been loaded successfully or not.
我针对低版本的API(最好是1.6,但可以去2.1),我需要知道是否声音已正确装入(因为它是由用户选择)。什么是正确的方式做到这一点?
I am targeting lower API version (ideally 1.6 but could go for 2.1) and I need to know whether a sound has been loaded correctly (as it is selected by the user). What's the proper way to do it?
我不希望用一次的MediaPlayer,如果正确使用的Soundpool加载声音?!
I hope not load the sound once with MediaPlayer and if correct with SoundPool?!
推荐答案
我实现了一种-兼容的 OnLoadCompleteListener
类的作品,至少为Android 2.1。
I implemented a kind-of-compatible OnLoadCompleteListener
class that works at least for Android 2.1.
构造函数使用的Soundpool
对象,声音为其 SoundPool.load(..)
已所谓的必须使用 OnLoadCompleteListener.addSound(soundId)注册
。在此之后,听者周期性尝试播放所请求的声音(在零体积)。如果成功的话,它会调用您的实现的onLoadComplete
,像在Android 2.2+版本。
The constructor takes a SoundPool
object, and sounds for which the SoundPool.load(..)
has been called must be registered with OnLoadCompleteListener.addSound(soundId)
. After this, the listener periodically attempts to play the requested sounds (at zero volume). If successful, it calls your implementation of onLoadComplete
, like in the Android 2.2+ version.
下面是一个使用示例:
SoundPool mySoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
OnLoadCompleteListener completionListener = new OnLoadCompleteListener(mySoundPool) {
@Override
public void onLoadComplete(SoundPool soundPool, int soundId, int status) {
Log.i("OnLoadCompleteListener","Sound "+soundId+" loaded.");
}
}
int soundId=mySoundPool.load(this, R.raw.funnyvoice,1);
completionListener.addSound(soundId); // tell the listener to test for this sound.
和这里的源:
abstract class OnLoadCompleteListener {
final int testPeriodMs = 100; // period between tests in ms
/**
* OnLoadCompleteListener fallback implementation for Android versions before 2.2.
* After using: int soundId=SoundPool.load(..), call OnLoadCompleteListener.listenFor(soundId)
* to periodically test sound load completion. If a sound is playable, onLoadComplete is called.
*
* @param soundPool The SoundPool in which you loaded the sounds.
*/
public OnLoadCompleteListener(SoundPool soundPool) {
testSoundPool = soundPool;
}
/**
* Method called when determined that a soundpool sound has been loaded.
*
* @param soundPool The soundpool that was given to the constructor of this OnLoadCompleteListener
* @param soundId The soundId of the sound that loaded
* @param status Status value for forward compatibility. Always 0.
*/
public abstract void onLoadComplete(SoundPool soundPool, int soundId, int status); // implement yourself
/**
* Method to add sounds for which a test is required. Assumes that SoundPool.load(soundId,...) has been called.
*
* @param soundPool The SoundPool in which you loaded the sounds.
*/
public void addSound(int soundId) {
boolean isFirstOne;
synchronized (this) {
mySoundIds.add(soundId);
isFirstOne = (mySoundIds.size()==1);
}
if (isFirstOne) {
// first sound, start timer
testTimer = new Timer();
TimerTask task = new TimerTask() { // import java.util.TimerTask for this
@Override
public void run() {
testCompletions();
}
};
testTimer.scheduleAtFixedRate(task , 0, testPeriodMs);
}
}
private ArrayList<Integer> mySoundIds = new ArrayList<Integer>();
private Timer testTimer; // import java.util.Timer for this
private SoundPool testSoundPool;
private synchronized void testCompletions() {
ArrayList<Integer> completedOnes = new ArrayList<Integer>();
for (Integer soundId: mySoundIds) {
int streamId = testSoundPool.play(soundId, 0, 0, 0, 0, 1.0f);
if (streamId>0) { // successful
testSoundPool.stop(streamId);
onLoadComplete(testSoundPool, soundId, 0);
completedOnes.add(soundId);
}
}
mySoundIds.removeAll(completedOnes);
if (mySoundIds.size()==0) {
testTimer.cancel();
testTimer.purge();
}
}
}
这篇关于知道如果用的Soundpool声音的加载已经成功在Android 1.6 / 2.0 / 2.1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!