Android多线程 - 播放声音和时间的时间回复

时间:2014-04-15 14:42:10

标签: java android multithreading audio

这个东西真的很新,所以忍受我!

在我的应用程序中,我需要提示用户通过按下按钮响应噪音,并在声音播放时记录响应。我还需要一个可变的声音呈现时间,以及声音之间的可变时间......

我面临的问题是我需要一种方法在声音的呈现之间发出延迟,并在声音播放和声音停止命令之间有延迟。我理解使用wait()我需要使用另一个线程,这样我就不会暂停UI线程。

我需要一些帮助,这是最优雅的方式吗?目前我有这个:

 public void onClick(View v) {

    switch (v.getId()){

        case R.id.start:


            presentTone(1000,60,2000,"l");
            // I need to insert a delay here, or in the presentTone method body 
            break;

我的presentTone方法就是这样:

private void presentTone(int frequency,int amplitude,final int length,String side){


// GETTING THE CORRECT AMPLITUDE LEVEL

    // Find the correction level as a float
    correctionDB = calibrationOffsets.get(frequency + "L");

    // Decibels for 5 dB drops
    volLog = (float) (Math.pow(10,((amplitude-100)/20)));

    // Multiply the decibels correction with the presentation level to get the calibrated level if the offset is positive
    volLog = (float) (volLog*(Math.pow(10,((correctionDB)/20))));

    // Check to see if the system is capable of the 80 dB desired level
    if (volLog>1){
        Toast.makeText(this, "Over Error - System is not capable of this amplitude level!" ,Toast.LENGTH_LONG).show();
    }


//PICKING THE CORRECT HEADPHONE SIDE TO PLAY

    volLogL = volLog;
    volLogR = volLog;

    if (side.toLowerCase().contains("l")){
        volLogR = (float) 0.0;
    }else if (side.toLowerCase().contains("r")){
        volLogL = (float) 0.0;
    }

//PLAYING THE TONE

    // Playing the tone
    mp.reset();
    mp = MediaPlayer.create(this,idReferences.get(freq_selection));
    mp.setVolume(volLogL, volLogR);
    mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            if (mp.isPlaying()) {
                mp.stop();
                mp.reset();
            }
            try {
                mp.start();{


//* I need to add a delay here, so I think I need to run the whole "Playing the tone" section in another thread?



                }
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
        }
    });

}

我需要新线程在presentTone方法中,这样我就可以开始播放,延迟一段时间,然后停止。我还需要反馈一个布尔值来判断声音是否正在播放,以便我可以处理用户响应。

道歉,如果我问的不清楚,我正在尽力让它变得明显!我很感激任何帮助。感谢

2 个答案:

答案 0 :(得分:0)

public void onClick(View v) {

switch (v.getId()){

    case R.id.start:

        new Thread(new Runnable(){
          public voir run(){
            Thread.sleep(_time_);
            presentTone(1000,60,2000,"l");
          }
        }).start();
        break;

这应该有用。

这样它就不会暂停主线程。

答案 1 :(得分:0)

这是一个小线程示例,您可以尝试并在您自己的情况下使用它。例如,此处的while循环仅由TaskObject的活动状态控制,但您可以添加自己的条件,或者向Task添加方法以控制循环。< / p>

Task将等同于您的presentTone(...)方法,这是您要在另一个主题中运行的任务。

public class Task implements Runnable {
    private final TaskObject object;
    private int executionTick = 0;

    public Task(final TaskObject object) {
        this.object = object;
    }

    @Override
    public void run() {
        this.object.start();
        try {
            while (this.object.isActive()) {
                if (this.executionTick == 10) {
                    this.object.stop();
                } else {
                    System.out.println(this.executionTick++ + ": " + this.object.getName());
                    Thread.sleep(1000L);
                }
            }
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }
}

TaskObject将是该任务管理的对象。在这里,我创建了一个通用的,但这相当于你的声音,音调或媒体来源。

public class TaskObject {
    private String name;
    private boolean active = false;

    public TaskObject(final String name) {
        this.name = name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public void start() {
        this.active = true;
    }

    public void stop() {
        this.active = false;
    }

    public boolean isActive() {
        return this.active;
    }
}

这是测试。

public class Test {
    public static void main(String[] args) throws Exception {
        // The object we want to manage or track with the task.
        TaskObject executedObject = new TaskObject("Foo");

        // Executing the task.
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(new Task(executedObject));
        executor.shutdown();

        // Wait in this thread and change the name of the object.
        Thread.sleep(3000L);
        executedObject.setName("New Name");

        // Wait for the end of the task.
        executor.awaitTermination(15L, TimeUnit.SECONDS);
    }
}

输出:

0: Foo
1: Foo
2: Foo
3: New Name
4: New Name
5: New Name
6: New Name
7: New Name
8: New Name
9: New Name

请注意,这只是一个通用示例,您可以更好地了解如何处理多线程实现,而不是复制粘贴! :)

如果您有任何疑问,请随时询问!