My Code:
public class MainActivity extends AppCompatActivity {
private Button mRecordBtn;
private TextView mRecordLabel;
private MediaRecorder mRecorder;
private String mFileName = null;
private static final String LOG_TAG = "Record_log";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecordLabel = (TextView) findViewById(R.id.recordLabel);
mRecordBtn = (Button) findViewById(R.id.recordBtn);
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName = "/recorded_audio.3gp";
mRecordBtn.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent motionEvent) {
if(motionEvent.getAction() == MotionEvent.ACTION_DOWN ){
startRecording();
mRecordLabel.setText("Recording in Progress");
}
else if (motionEvent.getAction() == MotionEvent.ACTION_UP){
stopRecording();
mRecordLabel.setText("Recording Stopped");
}
return false;
}
});
}
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start(); //I am getting a bug on this line
}
private void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
when I ran this code on my Samsung Galaxy s7 edge, as well as on the nexxus 7 emulator given by android studio the app crashes. I posted all of the code because im not sure exactly where its messing up. It crashes when I press the button. It as made to be a press and hold to record, and release to stop recording
Check if the issue is with permission recording audio.
Related
Purpose- I'm actually making doorbell kind of app, where on tapping a button ,app rings(plays a small audio) & on holding it app records audio till user holds it.
my objective- start recording when user holds button & stops when user releases button.
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = "AudioRecordTest";
private Button ring,record;
private String outputfile = null;
private MediaRecorder rec = null;
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
// Requesting permission to RECORD_AUDIO
private boolean permissionToRecordAccepted = false;
private String [] permissions = {Manifest.permission.RECORD_AUDIO};
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (!permissionToRecordAccepted ) finish();
}
private void startrec()
{
Log.e(LOG_TAG, "startRecording:Calling ");
rec = new MediaRecorder();
rec.setAudioSource(MediaRecorder.AudioSource.MIC);
rec.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
rec.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
outputfile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/rec.amr";
rec.setOutputFile(outputfile);
try {
rec.prepare();
rec.start();
} catch (IOException ioe2) {
}
Toast.makeText(MainActivity.this, "RECORDING STARTED", Toast.LENGTH_SHORT).show();
}
private void stoprec(){
rec.stop();rec.release();
Toast.makeText(MainActivity.this, "RECORDING STOPPED", Toast.LENGTH_SHORT).show();
Log.e(LOG_TAG, "stopRecording:Calling ");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ring = findViewById(R.id.ringbutton);
record =findViewById(R.id.recordbutton);
ring.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v1) {
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (IllegalStateException ise) {}
}
});
record.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(View v2, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) startrec();
else if (event.getAction() == MotionEvent.ACTION_UP) stoprec();
return true;}
});
}
}
Problem- app crashes on touching record button
if u know a better way to do this pls tell.
You should use OnTouchListener event and start recording on ACTION_DOWN and stop on ACTION_UP.
Please check this
How to use View.OnTouchListener instead of onClick
Instead of OnClick You should use OnTouch Listener event and start recording on ACTION_DOWN and stop on ACTION_UP do add permissions as well for audio recording.!
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
private MediaRecorder mRecorder = null;
private String mFileName = null;
mRecordButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
//if Button is Pressed.! or user Id Holding Button
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
startRecording();
Toast.makeText(context, "Hold To Record.!", Toast.LENGTH_SHORT).show();
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
//Do Nothing
stopRecording();
Toast.makeText(context, "Recorded.!", Toast.LENGTH_SHORT).show();
}
return false;
}
});
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
// Record to the external cache directory for visibility
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
//getExternalCacheDir().getAbsolutePath();
String id = new String(UUID.randomUUID().toString());
mFileName += "/recordedAudio/" + id + ".mp3";
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
Log.e(LOG_TAG, "Recording:Calling ");
}
private void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
Log.e(LOG_TAG, "stopRecording:Calling ");
}
i want to record an audio input for exactly one second using MediaRecorder. i get an error when i added
handler.postDelayed(..)
here's the code, can anyone tell me how can i fix it? i also tried to do that in seperate threads but it gets complicated when i need to call it from other classes.
public class AudioRecordTest extends Activity
{
private static final String LOG_TAG = "AudioRecordTest";
private static String mFileName = null;
private RecordButton mRecordButton = null;
private MediaRecorder mRecorder = null;
private final Handler handler=new Handler();
private void onRecord(boolean start) {
if (start)
startRecording();
handler.postDelayed(new Runnable(){
#Override
public void run()
{
stopRecording();
}
},1000);
}
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
}
private void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
class RecordButton extends Button {
boolean mStartRecording = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onRecord(mStartRecording);
if (mStartRecording) {
setText("Stop recording");
} else {
setText("Start recording");
}
mStartRecording = !mStartRecording;
}
};
public RecordButton(Context ctx) {
super(ctx);
setText("Start recording");
setOnClickListener(clicker);
}
}
public AudioRecordTest() {
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout ll = new LinearLayout(this);
mRecordButton = new RecordButton(this);
ll.addView(mRecordButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
setContentView(ll);
}
#Override
public void onPause() {
super.onPause();
if (mRecorder != null) {
mRecorder.release();
mRecorder = null;
}
}
}*
Let's say I have an activity(let's call it Activity 1). There is an editText on it which contains a string value, which has been saved. Now if I were to go to an audio recording activity, and record a sound, I would like for the sound recorded to use the string imported from Activity 1 as a filename. (e.g. if the editText word in Act 1 is "meow", then the recorded audio would be called "recmeow".mp3)
I have been able to transfer the string from Activity 1 to the recording activity (tested with toasts). However, when it comes to naming the file under the string itself, it keeps naming the file as 'recnull' instead.
I've tried a lot of things but I just can't get it to work. Can anyone please take a look and see what went wrong? Thanks in advance! This is the code for the recording activity:
public class SpellRecord extends Activity {
//declaration of a variable called namerec to contain imported string
String namerec;
private static final String LOG_TAG = "AudioRecordTest";
private static String mFileName = null;
private RecordButton mRecordButton = null;
private MediaRecorder mRecorder = null;
private PlayButton mPlayButton = null;
private MediaPlayer mPlayer = null;
private void onRecord(boolean start) {
if (start) {
startRecording();
} else {
stopRecording();
}
}
private void onPlay(boolean start) {
if (start) {
startPlaying();
} else {
stopPlaying();
}
}
private void startPlaying() {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
private void stopPlaying() {
mPlayer.release();
mPlayer = null;
}
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
}
private void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
class RecordButton extends Button {
boolean mStartRecording = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onRecord(mStartRecording);
if (mStartRecording) {
setText("Stop recording");
} else {
setText("Start recording");
}
mStartRecording = !mStartRecording;
}
};
public RecordButton(Context ctx) {
super(ctx);
setText("Start recording");
setOnClickListener(clicker);
}
}
class PlayButton extends Button {
boolean mStartPlaying = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onPlay(mStartPlaying);
if (mStartPlaying) {
setText("Stop playing");
} else {
setText("Start playing");
}
mStartPlaying = !mStartPlaying;
}
};
public PlayButton(Context ctx) {
super(ctx);
setText("Start playing");
setOnClickListener(clicker);
}
}
public SpellRecord() {
//here is where the filename is supposed to be where namerec contains string
//imported from Activity 1
//i have also tried declaring a string variable in here and called out to namerec
//it didn't work
//I have also tried putting String.valueOf(namerec) in place of namerec below
//didn't work too. and etc.
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/rec" + namerec + ".mp3";
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
//below is where i import the string from activity 1
String recN = getIntent().getStringExtra("dataN");
LinearLayout ll = new LinearLayout(this);
mRecordButton = new RecordButton(this);
ll.addView(mRecordButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
mPlayButton = new PlayButton(this);
ll.addView(mPlayButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
setContentView(ll);
//putting the string value from activity 1 into namerec
namerec = recN;
//toast below shows that namerec will show the string value correctly
Toast.makeText(getApplicationContext(), "show "+ namerec + " show",
Toast.LENGTH_LONG).show();
}
#Override
public void onPause() {
super.onPause();
if (mRecorder != null) {
mRecorder.release();
mRecorder = null;
}
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
/*View root = ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
root.setBackgroundResource(Color.BLUE);*/
}
You are setting mFilename in your constructor ("SpellRecord") which is called before onCreate. An activity's constructor is called the moment you create an instance of it, whereas onCreate is only to "create" the activity only after its launched.
I've create Audio recorder. When rotating my device the audio will be automatically saved. How can I avoid this ? I'm using Android 4.1.1 on device.
private MediaRecorder mRecorder = null;
private static final String LOG_TAG = "MediaAudioCapture";
ImageButton button_audio_button = (ImageButton) findViewById(R.id.audio_button);
button_audio_button.setOnClickListener(new OnClickListener() {
public void onClick(View record_button) {
ImageButton audio_button = (ImageButton) record_button;
if (!started_note_recording) {
if (!started_recording) {
startRecording();
audio_button.setImageResource(R.drawable.audio_red);
} else {
stopRecording();
audio_button.setImageResource(R.drawable.audio);
}
}
}
});
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setOutputFile(output.getAbsolutePath());
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
ImageButton button_audio_button = (ImageButton)findViewById(R.id.audio_button);
button_audio_button.setImageResource(R.drawable.audio);
}
}
});
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
stopWatch.start();
}
That's because when you rotate, activity will be reload. You can fix the orientation to portrait or you have to change your logic to retain the state on rotation.
EDIT: When I click the record button a second time ( to stop recording ) it force closes the app. The specific code for that event:
else if(isrec) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
isrec = false;
Toast.makeText( getApplicationContext(),"No longer recording!",Toast.LENGTH_SHORT).show();
}
(Original question):
I'm having trouble trying to get an app to record sound on a button click. I've included the code... and here's what my Toasts tell me:
after setAudioSource
after setOutputFile
isrec is not true
trying...
caught IO Exception...
Any help is greatly appreciated.
private OnClickListener micListener = new OnClickListener() {
boolean isrec = false;
public void onClick(View v) {
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
Toast.makeText( getApplicationContext(),"after setAudioSource",Toast.LENGTH_SHORT).show();
recorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
File outputFile = null;
outputFile = getFileStreamPath("output.amr");
recorder.setOutputFile(outputFile.getAbsolutePath());
Toast.makeText( getApplicationContext(),"after setOutputFile",Toast.LENGTH_SHORT).show();
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
if(!isrec) {
Toast.makeText( getApplicationContext(),"isrec is not true",Toast.LENGTH_SHORT).show();
try {
Toast.makeText( getApplicationContext(),"trying...",Toast.LENGTH_SHORT).show();
recorder.prepare();
recorder.start();
isrec = true;
Toast.makeText( getApplicationContext(),"Recording!",Toast.LENGTH_SHORT).show();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText( getApplicationContext(),"caught IllegalState Exception...",Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText( getApplicationContext(),"caught IO Exception...",Toast.LENGTH_SHORT).show();
}
} else if(isrec) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
isrec = false;
Toast.makeText( getApplicationContext(),"No longer recording!",Toast.LENGTH_SHORT).show();
}
}
};
First of all, you should use a boolean for isrec instead of a string
That :
FileDescriptor fileName = null;
recorder.setOutputFile(fileName);
That means you want to record on a file which is null
If you create a file, and you pass it as a parameter of your recorder, it should work.
Edit : Sometimes the release doesn't work when you want to stop the recorder.
So, just keep stop() and reset()
Try the following code for the main activity :
public class AudioRecordTestActivity extends Activity
{
private static final String LOG_TAG = "AudioRecordTest";
private static String mFileName = null;
private RecordButton mRecordButton = null;
private MediaRecorder mRecorder = null;
private PlayButton mPlayButton = null;
private MediaPlayer mPlayer = null;
private void onRecord(boolean start) {
if (start) {
startRecording();
} else {
stopRecording();
}
}
private void onPlay(boolean start) {
if (start) {
startPlaying();
} else {
stopPlaying();
}
}
private void startPlaying() {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
private void stopPlaying() {
mPlayer.release();
mPlayer = null;
}
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
}
private void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
class RecordButton extends Button {
boolean mStartRecording = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onRecord(mStartRecording);
if (mStartRecording) {
setText("Stop recording");
} else {
setText("Start recording");
}
mStartRecording = !mStartRecording;
}
};
public RecordButton(Context ctx) {
super(ctx);
setText("Start recording");
setOnClickListener(clicker);
}
}
class PlayButton extends Button {
boolean mStartPlaying = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onPlay(mStartPlaying);
if (mStartPlaying) {
setText("Stop playing");
} else {
setText("Start playing");
}
mStartPlaying = !mStartPlaying;
}
};
public PlayButton(Context ctx) {
super(ctx);
setText("Start playing");
setOnClickListener(clicker);
}
}
public AudioRecordTestActivity() {
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout ll = new LinearLayout(this);
mRecordButton = new RecordButton(this);
ll.addView(mRecordButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
mPlayButton = new PlayButton(this);
ll.addView(mPlayButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
setContentView(ll);
}
#Override
public void onPause() {
super.onPause();
if (mRecorder != null) {
mRecorder.release();
mRecorder = null;
}
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
and in the manifest file specify the following permissions
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Maybe this will help? The article will show you how to solve two issues:
Show the way to record WAV file.
Record audio with best quality as possible.