Android 如何在声音输入时触发振动?

Android 如何在声音输入时触发振动?,android,audio,mediarecorder,vibration,android-vibration,Android,Audio,Mediarecorder,Vibration,Android Vibration,我正在尝试创建一个android应用程序,过滤一个特定频率的蜂鸣声,使手机振动 我使用MediaRecorder类从手机的麦克风获取输入,通过使用该类,我可以录制、保存和播放输入。现在我需要我的手机在有哔哔声或任何声音时振动 输入由一根电线连接到手机的耳机插孔,因此我知道只有一个频率被输入 我有一个按钮,点击它开始录音。 我已经有权振动并在清单文件中记录 record.setOnClickListener(new View.OnClickListener() { @Ove

我正在尝试创建一个android应用程序,过滤一个特定频率的蜂鸣声,使手机振动

我使用MediaRecorder类从手机的麦克风获取输入,通过使用该类,我可以录制、保存和播放输入。现在我需要我的手机在有哔哔声或任何声音时振动

输入由一根电线连接到手机的耳机插孔,因此我知道只有一个频率被输入

我有一个按钮,点击它开始录音。 我已经有权振动并在清单文件中记录

record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    isRecording=true;
                    myAudioRecorder.prepare();
                    myAudioRecorder.start();
...
}
我也试着在网上搜索,发现了类似的问题,但我找不到任何正确的答案

但是,我可以让手机在点击另一个按钮时震动,这是代码的提示

 Vibrator vibrate;
    vibrate = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

        Btn1.setOnClickListener(new View.OnClickListener()

                                {
                                    @Override
                                    public void onClick(View v) {
                                       vibrate.vibrate(800);
                                    }
                                }
我试着调用录音机中的可控震源。start();功能,但这使手机振动,即使没有声音了。 我也试着从那里得到帮助,所以每当出现静音时,手机不应该振动,但我感到困惑,我不知怎么地理解,应该有一个布尔值,当有声音时,它会变为真,并使手机振动,但我无法将此逻辑转化为代码。 请让我知道在这种情况下我能做什么,我应该朝哪个方向搜索

更新 我发现toturial用于显示带有输入声音振幅的进度条,它工作得很好,我尝试在缓冲区中有一些值时使手机振动,现在即使振幅为零,它也会振动,我想这是因为每次振动都会产生噪音,导致手机振动。我无法通过TOAST检查函数,因为java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序。有什么建议吗?

试试这个:

Btn1.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            v.post(new Runnable() {

                @Override
                public void run() {

                    vibrate.vibrate(800);
                }
            });

        }
    });
您可以尝试以下方法:

    Handler handler;
    Runnable r;

            handler = new Handler();
                r = new Runnable() {
                    public void run() {

                    Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                    vib.vibrate(500);
                    handler.postDelayed(r, 1000);

                    }
                };
            handler.post(r);

对于您的主要问题,也许您可以检查声音的振幅,并且只有在达到最小阈值时才会振动。大概是这样的:

private class DetectAmplitude extends AsyncTask<Void, Void, Void> {

    private MediaRecorder mRecorder = null;
    private final static int MAX_AMPLITUDE = 32768;
    //TODO: Investigate what is the ideal value for this parameter
    private final static int MINIMUM_REQUIRED_AVERAGE = 5000;

    @Override
    protected Void doInBackground(Void... params) {
        Boolean soundStarted = true;
        if (mRecorder == null) {
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mRecorder.setOutputFile("/dev/null");
            try {
                mRecorder.prepare();
            } catch (IllegalStateException e) {
                soundStarted = false;
                Log.e(TAG, "Could not detect background noise. Error preparing recorder: " + e.getMessage());
            } catch (IOException e) {
                soundStarted = false;
                Log.e(TAG, "Could not detect background noise. Error preparing recorder: " + e.getMessage());
            }
            try {
                mRecorder.start();
            } catch (RuntimeException e) {
                Log.e(TAG, "Could not detect background noise. Error starting recorder: " + e.getMessage());
                soundStarted = false;
                mRecorder.release();
                mRecorder = null;
            }
        }

        if (soundStarted) {
            // Compute a simple average of the amplitude over one
            // second
            int nMeasures = 100;
            int sumAmpli = 0;
            mRecorder.getMaxAmplitude(); // First call returns 0
            int n = 0;
            for (int i = 0; i < nMeasures; i++) {
                if (mRecorder != null) {
                    int maxAmpli = mRecorder.getMaxAmplitude();
                    if (maxAmpli > 0) {
                        sumAmpli += maxAmpli;
                        n++;
                    }
                } else {
                    return null;
                }
                try {
                    Thread.sleep(1000 / nMeasures);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            mRecorder.stop();
            mRecorder.release();
            mRecorder = null;

            final float avgAmpli = (float) sumAmpli / n;

            if (avgAmpli > MINIMUM_REQUIRED_AVERAGE) {
                //TODO: Vibrate the device here
            }
        }
        return null;
    }
} 
否则,您需要以某种方式将方法的结论传递给
活动
,以便它运行
Toast

编辑:

如果您想从
按钮使用它,您可以在
活动的
onCreate()
调用上设置它的
OnClickListener
,并在那里执行
异步任务。例如:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    Button button = (Button)findViewById(R.id.your_button_id);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new DetectAmplitude().execute(new Void[]{});
        }
    });
}

我建议您在生产代码中使用此功能之前先查看一下。

您希望对音频进行采样,并立即对其进行分析

MediaRecorder对此似乎很高,它只捕获到文件。您可能希望使用,因为它提供了对输入样本的直接访问

为了检测特定音调,可以在输入样本上使用。这是我几年前做的一个例子


为了检测超过某个阈值的任何声音,可以对输入样本进行分析,并在响度达到阈值时触发。这是一个对麦克风发出的巨大噪音作出反应的话筒。

谢谢您的回复,但我需要在有声音时使手机振动,而不是单击,我已经能够做到这一点。请再次阅读问题。请解释一下代码,我对android不熟悉,对所有概念都不熟悉。您好,这听起来不错,但我无法找到一种方法开始录制按钮单击,您是否建议在AsyncTask中使用按钮onclicklistener方法,然后是受保护的Void doInBackground(里面有Void…params?Hi@momomopomo我用一个用法示例编辑了我的答案。希望有帮助。您可以使用
setOutputFile(“/dev/null”)
MediaRecorder上的
,以避免文件输出。此外,为了检测是否有噪音,媒体记录器只需在一小段时间内检查声音振幅即可。您的回答很好,但由于我需要开发android和其他一些初学者,如果只有android实现,那就太好了虽然引入了tations,但是由于逻辑非常优秀,我已经有了逻辑,我需要的是语法来实现它。此外,出于学习的目的,没有必要在没有完全实现的情况下更改使用的类。
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    Button button = (Button)findViewById(R.id.your_button_id);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new DetectAmplitude().execute(new Void[]{});
        }
    });
}