I want to create app in which when i click one time on button, audio recording should start for particular time (say 20 seconds) and then it should automatically stop the recording and it ask the user to save audio with edit text to enter name of audio.
Now the problem is what i want to implement is when user double click on same button, audio recording should start for 40 seconds and then same thing it should automatically stop after 40 seconds and then it ask the user's to enter the name of audio.
So i am confused in how to implement that when user click one time then recording start for 20 seconds and if it double clicked recording start for 40 seconds.
If any one have any idea or sample application or anything then please help me. I have searched a lot but not getting any solution from any where.
You can use this method..
public void recordAudio(String fileName) {
final MediaRecorder recorder = new MediaRecorder();
ContentValues values = new ContentValues(3);
values.put(MediaStore.MediaColumns.TITLE, fileName);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile("/sdcard/sound/" + fileName);
try {
recorder.prepare();
} catch (Exception e){
e.printStackTrace();
}
final ProgressDialog mProgressDialog = new ProgressDialog(MyActivity.this);
mProgressDialog.setTitle(R.string.lbl_recording);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setButton("Stop recording", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mProgressDialog.dismiss();
recorder.stop();
recorder.release();
}
});
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
public void onCancel(DialogInterface p1) {
recorder.stop();
recorder.release();
}
});
recorder.start();
mProgressDialog.show();
}
Check this link for your reference
1) http://www.devlper.com/2010/12/android-audio-recording-part-1/
2) http://www.devlper.com/2010/12/android-audio-recording-part-2/
Enjoy..!!!
You can do that in two way. One you can check double click on the button and another is check long item click :
To use OnItemLongClickListener:
Long Press is a recommeded interaction in the UI Guidelines, double touch is not.
It's what users expect; a user might not find a double touch action as they won't go looking for it
It's already handled in the API.
Implementing Double Touch will affect handling of single touches, because you'll have to wait to see if every single touch turns into a double touch before you can process it.
Sample to use Double click listener:
private static final long DOUBLE_PRESS_INTERVAL = 250; // in millis
private long lastPressTime;
private boolean mHasDoubleClicked = false;
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Get current time in nano seconds.
long pressTime = System.currentTimeMillis();
// If double click...
if (pressTime - lastPressTime <= DOUBLE_PRESS_INTERVAL) {
Toast.makeText(getApplicationContext(), "Double Click Event", Toast.LENGTH_SHORT).show();
mHasDoubleClicked = true;
}
else { // If not double click....
mHasDoubleClicked = false;
Handler myHandler = new Handler() {
public void handleMessage(Message m) {
if (!mHasDoubleClicked) {
Toast.makeText(getApplicationContext(), "Single Click Event", Toast.LENGTH_SHORT).show();
}
}
};
Message m = new Message();
myHandler.sendMessageDelayed(m,DOUBLE_PRESS_INTERVAL);
}
// record the last time the menu button was pressed.
lastPressTime = pressTime;
return true;
}
Hope Bellow code to save audio
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
if (Build.VERSION.SDK_INT >= 10) {
mRecorder.setAudioSamplingRate(44100);
mRecorder.setAudioEncodingBitRate(96000);
mRecorder.setMaxDuration(24000);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
} else {
mRecorder.setAudioSamplingRate(8000);
mRecorder.setAudioEncodingBitRate(12200);
mRecorder.setMaxDuration(24000);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
}
String path = mFileName + String.valueOf(count) + ".amr";
mRecorder.setOutputFile(path);
try {
mRecorder.prepare();
mRecorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
in the bellow snippet to change the time . you should give time in millis
mRecorder.setMaxDuration(24000);
http://androidcodeexamples.blogspot.in/2012/06/voice-recording-in-android.html
please follow this link.
Made Changes in the Code : For Button start click event, define boolean variable
change boolean variable value on StartButton click event.
if boolean variable is true, set recordTime 20s otherwise recordTime 40s and start recording.
When you again start the recording, please stop the recording and reset the recorder.
Hope this can be useful.
Related
I found and use some method bellow but it is not work for me:
myThread.stop() //it is not safe but I am tried that
myThread.interupt
Here is my program: I wanna play video using Videoview when video finish. If user no choose the next video in 120s then my app will finish.
My video view code:
Uri uri = Uri.parse(filePath);
videoView = findViewById(R.id.videoView);
videoView.setVideoURI(uri);
waitingThread w8 = new waitingThread();
//set params video before play
videoView.setOnPreparedListener(mediaPlayer -> {
PlaybackParams playbackParams = new PlaybackParams();
playbackParams.setSpeed(DeviceConfig.getInstance().getVideoPeed());// 1.25 1.5 2 2.5
mediaPlayer.setPlaybackParams(playbackParams);
// I am tryied using stop thread here
// w8.stop()
// or w8.interrupt();
videoView.start();
});
videoView.setOnErrorListener((mediaPlayer, i, i1) -> {
Log.d(TAG,"Video Error");
//send error message to server
return false;
});
//I call thread when video complete
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
**waiting();** -> w8.start //edited i start thread here
}
});
My thread waiting
private class waitingThread extends Thread{
public void run() {
try {
while (!isInterrupted()) {
timeCount ++;
Thread.sleep(1000);
Log.d(TAG, "Time count : " + timeCount);
if(timeCount == 120){
finish();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//i am try to using this funtion but still not work too.
public void stopping(){
Thread.currentThread().interrupt();
// timeCount = 0;
// Log.d(TAG, "Stopping, reset time :" + timeCount);
}
}
Brief my idea: When video start play, thread waiting will be stopped. When video finish program will waiting a time if no video chose in time to wait program will finish, if any video chose then thread w8 stop.
My problem: when I choose the next video, my thread "w8" still keep running. That is make my app finished while video playing
Plz help me how to fix that problem or any same idea to work are appreciated
You don't want to call interrupt on Thread.currentThread. Thread.currentThread is the thread currently running- it's the thread you're calling the function on. It's not the thread object you just created. Instead it would be this.interrupt(). Or just get rid of the function entirely and call interrupt directly.
Introducing your own boolean variable might help
class waitingThread extends Thread{
boolean stop;
public void run(){
while(!stop){
//your task
}
stop = false; //
}
public void stopping(){
stop= true;
}
}
Hi I am using android with java. I have set up a very simple button which when held down records audio and when released stops recording. I have two questions:
When I run the following implementation of my idea, I get runtime a warning mediarecorder went away with unhandled events every time the button is released. I can't find what is causing this! I see that this has been answered previously on this forum many years ago with the suggestion to add mediaRecorder.update(), but this does not address why the warning is occurring. What does it mean by unhandled events and what could be causing it? I have done nothing different I can see than in the documentation, other than using an onTouchListener...
Second, should I be wary of user's being able to switch on and off the button very rapidly - could this cause runtime problems and should I take steps to guard against this?
The relevant code I use is more-or-less this:
public void set() {
View.OnTouchListener recordOnTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if (requestMultiplePermissions(Permissions).granted) {
audioSetup();
recordAudio();
}
return true;
case MotionEvent.ACTION_UP:
stopAudio();
return true;
default:
return false;
}
}
binding.addnewvocabRecordVocab.setOnTouchListener(recordOnTouchListener)
}
where
private void audioSetup() {
File filedir = new File(filepath);
if (!filedir.exists()) {filedir.mkdirs();
file = new File(filepath,filename);
if (file.exists()) { file.delete();}
}
public void recordAudio () {
isRecording = true;
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
try {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(file);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.prepare();
} catch (Exception e) {
e.printStackTrace();
}
mediaRecorder.start();
}
public void stopAudio () {
if (isRecording) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
isRecording = false;
}
}
This isn't a full answer to my own question, and the question still stands. But after playing with this a while, I have learnt a few lessons.
If the user taps the record button for a second, then mediarecorder.stop() will produce an error if there is not sufficient data recorded. See this. So if one wants to prevent the app from crashing, one needs to wrap mediarecorder.stop() in some catch - as the discussion in the link advises us. In fact, on some shortish taps, the stop method seems to take rather a long time (well over a second), so it might be worth considering disabling the button just before and after the stop method is called.
Another problem with fast repeated tapping is that it seems to keep adding to the main thread queue, which is probably inadvisable. I have found that using an executor thread with submit is a nice way of dealing with this. Schematically we can
public class audioLibrary() {
//or could go directly in main code
ExecutorService executor;
public void onStartRecord() {
if (executor == null) {
this.executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
//check isRecording and record stuff
});
}
}
public void onStopRecord() {
if (executor != null) {
executor.submit(() -> {
//check isRecording and shut down mediarecorder
//together with catch for onStop.
});
executor.shutdown();
}
}
}
Clearly, one must be a little careful to make sure the thread really does always get shut down.
Curiously, I do not get the `unhandled events' when I do this now...
Maybe someone could expand on this and comment on my code above to see whether they agree with the gist of it, whether it is necessary and on possible improvements.
I am trying to create an android application where I filter one specific frequency of a beep and make the phone vibrate.
I am taking input from the MIC of mobile and using MediaRecorder class, by using this class, I can record, save and play the input. Now I need my mobile to vibrate whenever there is a beep/or any sound.
The input is given by a wire to the Headphone jack of the mobile so I know that there is only one frequency being input.
I have a button, Clicking which starts recording.
I have Permissions to vibrate and record in my manifest file already.
record.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
isRecording=true;
myAudioRecorder.prepare();
myAudioRecorder.start();
...
}
I also tried to search the internet and found kind of the similar question here but I am unable to find any correct answer.
However, I can make the phone vibrate on clicking another button and here is the snipt of code,
Vibrator vibrate;
vibrate = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
Btn1.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
vibrate.vibrate(800);
}
}
I tried calling a Vibrator inside recorder.start(); function but this makes the phone vibrate even when there is no sound anymore.
I also tried getting help from this question so whenever there is silence, the phone should not vibrate, but I am getting confused, I somehow understand that there should be a Boolean which gets true when there is sound and make the phone vibrate, but I am unable to put this logic into code.
Please let me know what can I do in this context and which direction should I be searching in?
UPDATE
I found this toturial for showing the progress bar with amplitude of input sound, it works fine and I tried to make the phone vibrate when there is some value in buffer, Now it vibrates even when the amplitude is zero, I guess thats because of the fact that every vibration makes noise which leads the phone to vibrate. I am unable to check the function via TOAST because of java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare(). Is there any suggestion?
For your main problem, maybe you can check for the amplitude of the sound, and only vibrate if a minimum threshold has been reached. Something like this:
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;
}
}
For more information regarding the detection of sound level, please refer to the following:
android: detect sound level
What does Android's getMaxAmplitude() function for the MediaRecorder actually give me?
Regarding the exception java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare(), that is happening because the Toast needs to run on the main thread of your app. If your Thread code (like an AsyncTask) is inside an Activity, you can try the following:
runOnUiThread(new Runnable() {
#Override
public void run() {
//Call your Toast here
}
});
Otherwise, you need to somehow pass the conclusion of your method to the Activity for it to run the Toast.
EDIT:
If you want to use this from a Button, you could set its OnClickListener on your Activity's onCreate() call and execute the AsyncTask there. For example:
#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[]{});
}
});
}
I suggest you take a look at how AsyncTask works before using this in production code.
You want to sample the audio, and analyze it immediately.
MediaRecorder seems to high level for this, it only captures to file. You probably want to use AudioRecorder instead, as it gives direct access to the input samples.
In order to detect a specific tone, you can use the Goertzel algorithm on the input samples. Here is a C++ implementation I did years ago that could serve as an example.
In order to detect any sound over a certain threshold, you can use Root Mean Square analysis on the input samples and make it trigger once the loudness reaches your threshold. Here is a Python example that reacts to loud noises from a microphone.
Try this:
Btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.post(new Runnable() {
#Override
public void run() {
vibrate.vibrate(800);
}
});
}
});
You can try this:
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);
I am working on a video recording camera APP. App crashes if camera is stopped right after starting it maybe because of video size very less. I want to activate stop button only if video size is greater than 1 sec. But problem is I cannot find Current Time and Start time correctly. Finding the difference of two time factors will help in implementing 2 sec Check. Need Help please.
private void onClickActions(View v)
{
float tt = start_time /10000000000000f;
float ct = ((System.currentTimeMillis() ) /10000000000000f);
Log.d("Before stoping S-Time ",tt+"");
Log.d("Before stoping C-Time ",ct+"");
if (recording && tt>=2.0f)
{
Log.d("After Stopping = ",tt+"");
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
recording = false;
rec.setVisibility(View.INVISIBLE);
start_time = 0;
}
//remove time code to initial revert
if(v.getId()== start.getId() && ((CameraPreview.recordHappy || CameraPreview.recordSad))) {
prepareMediaRecorder();
recording = true;
mediaRecorder.start();
consent = true;
happyRecorded=true;
stop.setClickable(true);
start.setClickable(false);
if (AndroidVideoCaptureExample.iV.getVisibility()==View.VISIBLE)
AndroidVideoCaptureExample.iV.setVisibility(View.INVISIBLE);
//AndroidVideoCaptureExample.capture.setText("RECORDING STARTED!");
rec.setVisibility(View.VISIBLE);
start_time = (int)(System.currentTimeMillis());
//Toast.makeText(myContext, "You are being recorded now!", Toast.LENGTH_LONG);
}
if(v.getId()== stop.getId() && consent==true && recording==false) {
if((!CameraPreview.recordHappy && CameraPreview.recordSad))
{
releaseMediaRecorder(); // release the MediaRecorder object
Intent intent = new Intent();
intent.setClass(AndroidVideoCaptureExample.this, consentActivity.class);
startActivity(intent);
finish();
}
else {
CameraPreview.recordHappy = false;
CameraPreview.recordSad = true;
stop.setClickable(false);
start.setClickable(true);
recording = false;
AndroidVideoCaptureExample.capture.setText("Record Neutral Moment");
rec.setVisibility(View.INVISIBLE);
}
}
}
I think you might be overengineering a simple thing. You don't really need to count record time unless you are showing it on the UI. If you want to disable the button, simply disable it just before starting the recording, then use Handler to re-enable after 2 seconds:
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
// enable stop button
}
},2000);
However, I would argue that's not a very good user experience. If you look at cameras like Google Camera, you can stop it immediately after starting, it just won't record anything. To achieve this, you need to catch the RuntimeException when calling mediaRecorder.stop(), then check and clean up the generated file. If it's empty then delete it and don't throw an error to the UI.
I'm developing on a Nitro HD with Gingerbread. I want to record audio and I experience an infinite hang while calling MediaRecorder.stop().
I know that my phone can record sound because I have an application that does it exactly.
I read the book "Android for programmers" from Deitel et al. and there is the example VoiceRecorder in chapter 16. Everything seems fine but the app hangs forever when it calls MediaRecorder.stop(). Also, the resource is not released and I have to reboot the phone to release it.
Here is the part of the code where the calls are done (see Deitel et al., "Android for Programmers", Prentice Hall, 2012, chap 16):
// starts/stops a recording
OnCheckedChangeListener recordButtonListener =
new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked)
{
if (isChecked)
{
visualizer.clear(); // clear visualizer for next recording
saveButton.setEnabled(false); // disable saveButton
deleteButton.setEnabled(false); // disable deleteButton
viewSavedRecordingsButton.setEnabled(false); // disable
// create MediaRecorder and configure recording options
if (recorder == null)
recorder = new MediaRecorder(); // create MediaRecorder
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(
MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioEncodingBitRate(16);
recorder.setAudioSamplingRate(44100);
try
{
// create temporary file to store recording
File tempFile = File.createTempFile(
"VoiceRecorder", ".3gp", getExternalFilesDir(null));
// store File as tag for saveButton and deleteButton
saveButton.setTag(tempFile);
deleteButton.setTag(tempFile);
// set the MediaRecorder's output file
recorder.setOutputFile(tempFile.getAbsolutePath());
recorder.prepare(); // prepare to record
recorder.start(); // start recording
recording = true; // we are currently recording
handler.post(updateVisualizer); // start updating view
} // end try
catch (IllegalStateException e)
{
Log.e(TAG, e.toString());
} // end catch
catch (IOException e)
{
Log.e(TAG, e.toString());
} // end catch
} // end if
else
{
recorder.stop(); // stop recording
recorder.reset(); // reset the MediaRecorder
recording = false; // we are no longer recording
saveButton.setEnabled(true); // enable saveButton
deleteButton.setEnabled(true); // enable deleteButton
recordButton.setEnabled(false); // disable recordButton
} // end else
} // end method onCheckedChanged
}; // end OnCheckedChangedListener
In a debug session, the "else" scope is entered but it hangs on its first (stop()) line.
I repeat, I know the phone and its OS are correct because another app works correctly. So, do you have any idea on how to solve this problem, a work around maybe?
Thanks!
EDIT When the recorder is started(), there is a handler that is executed at each 50ms to display a graph of the amplitude of the sound. The method recorder.getMaxAmplitude() always returns 0. Maybe this is the symptom of a badly initialized MediaRecorder?
The argument of setAudioEncodingBitRate() might be too low.
what is good setAudioEncodingBitRate on record voice
Hope that's help.
You could have a null recorder at that spot. You're not creating a new MediaRecorder() if you enter the else case of isChecked.
So, 2 things:
The API docs state that if you call stop() before start you'll throw a RuntimeException And if you fail to record anything you'll throw an IllegalStateException.
Check recorder before calling stop:
if (recorder != null) {
recorder.stop();
// some recorder stuff here
}