使用SoundPool、Timer和TimerTask每分钟随机播放一段声音
Using SoundPool, Timer and TimerTask to play a random sound every minute
我试图每分钟播放一个随机声音,提示用户与设备进行交互。我正在使用 SoundPool、Timer 和 TimerTask 来尝试实现这一目标。播放声音时,我还使用 Logcat 查看要播放的声音的 ID(这用于研究和数据分析目的)。我尝试了几种方法,包括在 TimerTask 运行() 方法内部和外部初始化 SoundPool,以及在单击按钮后释放 SoundPool。 timer.Schedule 用于将 TimerTask 安排到 运行,我应该将这些设为静态吗?
logcat 正在记录 SoundId,但声音播放不一致。例如,它将播放第一个声音并记录,然后它会在不播放声音的情况下记录其他 SoundId。即使已按下按钮并且已释放 SoundPool 的资源,也会发生这种情况。有时甚至根本不会播放声音。
任何人都可以告诉我为什么这会不一致或更好的方法吗?
public class TouchscreenDashboard extends AppCompatActivity implements View.OnClickListener {
private SoundPool soundPool;
int[] sounds={R.raw.decrease_fan_speed_by_2, R.raw.decrease_fan_speed_by_5,
R.raw.increase_fan_speed1, R.raw.increase_fan_speed_by_3,R.raw.lower_temp1,
R.raw.lower_temp4, R.raw.raise_temp2, R.raw.raise_temp3 ,R.raw.skip_backwards_2_songs,
R.raw.skip_backwards_4_songs,R.raw.skip_forward_1_song, R.raw.skip_forward_5_songs,
R.raw.volume_down3,R.raw.volume_down6, R.raw.volume_up3, R.raw.volume_up5};
private Button volumeUp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
Log.i("DashboardActivity", "Dashboard has started");
Timer timer = new Timer() {};
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.build();
soundPool = new SoundPool.Builder()
.setAudioAttributes(audioAttributes)
.build();
Random r = new Random();
int Low = 0;
int High = 16;
int random = r.nextInt(High-Low) + Low;
int soundId = soundPool.load(getApplicationContext(), sounds[random], 1);
soundPool.play(soundId, 1, 1, 0, 0, 1);
Log.i("DashboardActivity", "SoundId: " + random);
}
};
timer.schedule(timerTask, 60000, 60000);
volumeUp = findViewById(R.id.volumeUp);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.volumeUp:
if (volumeCount < 99) {
volumeCount++;
volumeText.setText(Integer.toString(volumeCount));
}
soundPool.release();
Log.i("DashboardActivity", "Volume Up Clicked");
break;
}
}
}
所以,经过多次强调,我有一个可行的解决方案!我仍然认为必须有更好的方法来做到这一点,但这就是我想出的。 setOnLoadCompleteListener 现在仅在加载一次时播放声音,并且 timerTask2 比 timerTask1 晚 5 秒运行。延迟 5 秒的原因是我的声音都在 1-3 秒以下。
public class TouchscreenDashboard extends AppCompatActivity implements View.OnClickListener {
int[] sounds={R.raw.decrease_fan_speed_by_2, R.raw.decrease_fan_speed_by_5,
R.raw.increase_fan_speed1, R.raw.increase_fan_speed_by_3,R.raw.lower_temp1,
R.raw.lower_temp4, R.raw.raise_temp2, R.raw.raise_temp3 ,R.raw.skip_backwards_2_songs,
R.raw.skip_backwards_4_songs,R.raw.skip_forward_1_song, R.raw.skip_forward_5_songs,
R.raw.volume_down3,R.raw.volume_down6, R.raw.volume_up3, R.raw.volume_up5};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
Log.i("DashboardActivity", "Dashboard has started");
startTimer();
}
public void startTimer() {
timer = new Timer();
timer2 = new Timer();
initializeTimerTask();
initializeTimerTask2();
timer.schedule(timerTask, randomTimeInt, randomTimeInt); //
timer2.schedule(timerTask2, randomTimeInt + 5000, randomTimeInt);
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
@Override
public void run() {
audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.build();
soundPool = new SoundPool.Builder()
.setAudioAttributes(audioAttributes)
.build();
releaseSoundpool = true;
Random r = new Random();
int Low = 0;
int High = 16;
int random = r.nextInt(High-Low) + Low;
final int soundId = soundPool.load(getApplicationContext(), sounds[random], 1);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundPool.play(soundId, 1, 1, 1, 0, 1);
}
});
Log.d("TouchscreenDashboard", "soundID played: " + random);
}
};
}
public void initializeTimerTask2() {
timerTask2 = new TimerTask() {
@Override
public void run() {
soundPool.release();
Log.d("TouchscreenDashboard", "SoundPool released");
}
};
}
我真的希望这对其他人有帮助。
我试图每分钟播放一个随机声音,提示用户与设备进行交互。我正在使用 SoundPool、Timer 和 TimerTask 来尝试实现这一目标。播放声音时,我还使用 Logcat 查看要播放的声音的 ID(这用于研究和数据分析目的)。我尝试了几种方法,包括在 TimerTask 运行() 方法内部和外部初始化 SoundPool,以及在单击按钮后释放 SoundPool。 timer.Schedule 用于将 TimerTask 安排到 运行,我应该将这些设为静态吗?
logcat 正在记录 SoundId,但声音播放不一致。例如,它将播放第一个声音并记录,然后它会在不播放声音的情况下记录其他 SoundId。即使已按下按钮并且已释放 SoundPool 的资源,也会发生这种情况。有时甚至根本不会播放声音。
任何人都可以告诉我为什么这会不一致或更好的方法吗?
public class TouchscreenDashboard extends AppCompatActivity implements View.OnClickListener {
private SoundPool soundPool;
int[] sounds={R.raw.decrease_fan_speed_by_2, R.raw.decrease_fan_speed_by_5,
R.raw.increase_fan_speed1, R.raw.increase_fan_speed_by_3,R.raw.lower_temp1,
R.raw.lower_temp4, R.raw.raise_temp2, R.raw.raise_temp3 ,R.raw.skip_backwards_2_songs,
R.raw.skip_backwards_4_songs,R.raw.skip_forward_1_song, R.raw.skip_forward_5_songs,
R.raw.volume_down3,R.raw.volume_down6, R.raw.volume_up3, R.raw.volume_up5};
private Button volumeUp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
Log.i("DashboardActivity", "Dashboard has started");
Timer timer = new Timer() {};
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.build();
soundPool = new SoundPool.Builder()
.setAudioAttributes(audioAttributes)
.build();
Random r = new Random();
int Low = 0;
int High = 16;
int random = r.nextInt(High-Low) + Low;
int soundId = soundPool.load(getApplicationContext(), sounds[random], 1);
soundPool.play(soundId, 1, 1, 0, 0, 1);
Log.i("DashboardActivity", "SoundId: " + random);
}
};
timer.schedule(timerTask, 60000, 60000);
volumeUp = findViewById(R.id.volumeUp);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.volumeUp:
if (volumeCount < 99) {
volumeCount++;
volumeText.setText(Integer.toString(volumeCount));
}
soundPool.release();
Log.i("DashboardActivity", "Volume Up Clicked");
break;
}
}
}
所以,经过多次强调,我有一个可行的解决方案!我仍然认为必须有更好的方法来做到这一点,但这就是我想出的。 setOnLoadCompleteListener 现在仅在加载一次时播放声音,并且 timerTask2 比 timerTask1 晚 5 秒运行。延迟 5 秒的原因是我的声音都在 1-3 秒以下。
public class TouchscreenDashboard extends AppCompatActivity implements View.OnClickListener {
int[] sounds={R.raw.decrease_fan_speed_by_2, R.raw.decrease_fan_speed_by_5,
R.raw.increase_fan_speed1, R.raw.increase_fan_speed_by_3,R.raw.lower_temp1,
R.raw.lower_temp4, R.raw.raise_temp2, R.raw.raise_temp3 ,R.raw.skip_backwards_2_songs,
R.raw.skip_backwards_4_songs,R.raw.skip_forward_1_song, R.raw.skip_forward_5_songs,
R.raw.volume_down3,R.raw.volume_down6, R.raw.volume_up3, R.raw.volume_up5};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
Log.i("DashboardActivity", "Dashboard has started");
startTimer();
}
public void startTimer() {
timer = new Timer();
timer2 = new Timer();
initializeTimerTask();
initializeTimerTask2();
timer.schedule(timerTask, randomTimeInt, randomTimeInt); //
timer2.schedule(timerTask2, randomTimeInt + 5000, randomTimeInt);
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
@Override
public void run() {
audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.build();
soundPool = new SoundPool.Builder()
.setAudioAttributes(audioAttributes)
.build();
releaseSoundpool = true;
Random r = new Random();
int Low = 0;
int High = 16;
int random = r.nextInt(High-Low) + Low;
final int soundId = soundPool.load(getApplicationContext(), sounds[random], 1);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundPool.play(soundId, 1, 1, 1, 0, 1);
}
});
Log.d("TouchscreenDashboard", "soundID played: " + random);
}
};
}
public void initializeTimerTask2() {
timerTask2 = new TimerTask() {
@Override
public void run() {
soundPool.release();
Log.d("TouchscreenDashboard", "SoundPool released");
}
};
}
我真的希望这对其他人有帮助。