Karolis.L Karolis.L - 13 days ago 7
Android Question

"java.lang.RuntimeException: start failed." when trying to run MediaRecorder.start() method

I'm currently trying to build an application that includes a sound recorder. While doing so, I've encountered a problem which I cannot solve, even though I've googled the whole Internet and read a number of threads. So here's the thing. I create an instance of MediaRecorder. However, each time I try to run the .start() method via OnClick, the app crashes. I've asked for permissions in the Manifest file, as well as manually via main onCreate() method. However, seems like it has nothing to do with that. I've also seen many topics that tell people to run .prepare() method before .start(). However, I've done that before starting the research. Hence, this is not the case. I'm adding all the information below.

The crash log:

--------- beginning of crash
04-04 17:36:16.631 2605-2605/com.liucveikis.beatboxjam E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.liucveikis.beatboxjam, PID: 2605
java.lang.RuntimeException: start failed.
at android.media.MediaRecorder.start(Native Method)
at com.liucveikis.beatboxjam.SoundRecorderActivity\$1.onClick(SoundRecorderActivity.java:56)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
04-04 17:36:16.632 1612-1983/system_process W/ActivityManager: Force finishing activity com.liucveikis.beatboxjam/.SoundRecorderActivity


Manifest include:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />


Manual permission demand:

int YOUR_REQUEST_CODE = 200;

if(ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) //check if permission request is necessary
ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, YOUR_REQUEST_CODE);
}


}


Sound recording activity:

package com.liucveikis.beatboxjam;

import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.IOException;

public class SoundRecorderActivity extends AppCompatActivity {

private Button play, stop, record, save;
private MediaRecorder audioRecorder;
private String outputFile;
private boolean permissionToRecordAccepted = false;
private boolean permissionToWriteAccepted = false;
private String [] permissions = {"android.permission.RECORD_AUDIO", "android.permission.WRITE_EXTERNAL_STORAGE"};



@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sound_recorder);

play = (Button) findViewById(R.id.playRecord);
stop = (Button) findViewById(R.id.stopRecording);
record = (Button) findViewById(R.id.startRecording);
save = (Button) findViewById(R.id.saveRecord);

play.setEnabled(false);
stop.setEnabled(false);
save.setEnabled(false);



outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp";
audioRecorder = new MediaRecorder();
audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
audioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AAC_ADTS);
audioRecorder.setOutputFile(outputFile);

record.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
try {
audioRecorder.prepare();
audioRecorder.start();
} catch (IllegalStateException e) {

} catch (IOException e) {

}

record.setEnabled(false);
stop.setEnabled(false);

Toast.makeText(getApplicationContext(), "Recording Started", Toast.LENGTH_LONG).show();
}
});

stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
audioRecorder.stop();
audioRecorder.release();
audioRecorder = null;
stop.setEnabled(false);
play.setEnabled(true);
Toast.makeText(getApplicationContext(), "Recorded Successfully", Toast.LENGTH_LONG).show();
}
});

play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaPlayer mediaPlayer = new MediaPlayer();

try {
mediaPlayer.setDataSource(outputFile);
mediaPlayer.prepare();
mediaPlayer.start();

Toast.makeText(getApplicationContext(), "Record Is Playing", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
});

}
}


2017-04-05 changes to Sound recording activity - it still doesnt work.

package com.liucveikis.beatboxjam;

import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.IOException;

public class SoundRecorderActivity extends AppCompatActivity {

private static final String LOG_TAG = "LALALALALALALA";
private Button play, stop, record, save;
private MediaRecorder audioRecorder;
private String outputFile;
private boolean permissionToRecordAccepted = false;
private boolean permissionToWriteAccepted = false;
private String [] permissions = {"android.permission.RECORD_AUDIO", "android.permission.WRITE_EXTERNAL_STORAGE"};



@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sound_recorder);

play = (Button) findViewById(R.id.playRecord);
stop = (Button) findViewById(R.id.stopRecording);
record = (Button) findViewById(R.id.startRecording);
save = (Button) findViewById(R.id.saveRecord);

play.setEnabled(false);
stop.setEnabled(false);
save.setEnabled(false);




/* audioRecorder = new MediaRecorder();
audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
audioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AAC_ADTS);
audioRecorder.setOutputFile(outputFile);*/




record.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {

outputFile = getFilesDir().getAbsolutePath() + "/recording.3gp";
audioRecorder = new MediaRecorder();
audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
audioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
audioRecorder.setOutputFile(outputFile);

try {
audioRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}

audioRecorder.start();

record.setEnabled(false);
stop.setEnabled(true);

Toast.makeText(getApplicationContext(), "Recording Started", Toast.LENGTH_LONG).show();
}
});




stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
audioRecorder.stop();
audioRecorder.release();
audioRecorder = null;
stop.setEnabled(false);
play.setEnabled(true);
Toast.makeText(getApplicationContext(), "Recorded Successfully", Toast.LENGTH_LONG).show();
}
});




play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MediaPlayer mediaPlayer = new MediaPlayer();

try {
mediaPlayer.setDataSource(outputFile);
mediaPlayer.prepare();
mediaPlayer.start();

Toast.makeText(getApplicationContext(), "Record Is Playing", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
});



}
}


-------------------EDIT: 2017-04-17-------------------

Alright, so I've completely rewritten the Recorder class. However, now I'm facing a bit different issue. The thing works perfectly on Android 6.0 (API 23) and Android 7.0 (API 24), but crashes on Android 7.1.1 (API 25). Have there been some changes or something regarding the MediaRecorder? Permissions are granted, no need to worry about that.

package com.liucveikis.beatboxjam;


import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.io.File;
import java.io.IOException;

public class SoundRecorderActivity extends AppCompatActivity {

private Button startRecording, stopRecording, playRecord, saveRecord;
private MediaPlayer player;
private MediaRecorder recorder;
private String FILE;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sound_recorder);

startRecording = (Button)findViewById(R.id.startRecording);
stopRecording = (Button)findViewById(R.id.stopRecording);
playRecord = (Button)findViewById(R.id.playRecord);
saveRecord = (Button)findViewById(R.id.saveRecord);

startRecording.setEnabled(true);
stopRecording.setEnabled(false);
playRecord.setEnabled(false);
saveRecord.setEnabled(false);

FILE = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tempRecord.3gp";


startRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
startRecording();
stopRecording.setEnabled(true);
startRecording.setEnabled(false);
} catch (IOException e) {
e.printStackTrace();
}
}
});


stopRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopRecording();
stopRecording.setEnabled(false);
startRecording.setEnabled(true);
playRecord.setEnabled(true);
}
});


playRecord.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
startPlaying();
} catch (IOException e) {
e.printStackTrace();
}
}
});


}



public void startRecording() throws IOException {
if(recorder!=null){
recorder.stop();
recorder.release();
}

File fileOutput = new File(FILE);
if(fileOutput!=null){
fileOutput.delete();
}

recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(FILE);


recorder.prepare();
recorder.start();

}


public void stopRecording(){
recorder.stop();
recorder.release();
}

public void startPlaying() throws IOException {

if(player!=null){
player.stop();
player.release();
}

player = new MediaPlayer();
player.setDataSource(FILE);
player.prepare();
player.start();

player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer player) {
player.release();
}
});

}
}


The error:

04-12 19:46:24.911 1335-1335/? W/APM_AudioPolicyManager: getInputForAttr() failed opening input: samplingRate 8000, format 1, channelMask 10
04-12 19:46:24.911 1343-1343/? E/AudioRecord: Could not get audio input for session 73, record source 1, sample rate 8000, format 0x1, channel mask 0x10, flags 0
04-12 19:46:24.911 1343-1343/? E/StagefrightRecorder: audio source is not initialized
04-12 19:46:24.911 2592-2592/com.liucveikis.beatboxjam E/MediaRecorder: start failed: -2147483648
04-12 19:46:24.911 2592-2592/com.liucveikis.beatboxjam D/AndroidRuntime: Shutting down VM


--------- beginning of crash
04-12 19:46:24.912 2592-2592/com.liucveikis.beatboxjam E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.liucveikis.beatboxjam, PID: 2592
java.lang.RuntimeException: start failed.
at android.media.MediaRecorder.start(Native Method)
at com.liucveikis.beatboxjam.SoundRecorderActivity.startRecording(SoundRecorderActivity.java:101)
at com.liucveikis.beatboxjam.SoundRecorderActivity$1.onClick(SoundRecorderActivity.java:45)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
04-12 19:46:24.914 1614-1680/system_process W/ActivityManager: Force finishing activity com.liucveikis.beatboxjam/.SoundRecorderActivity

Answer

The initial post got really messy, so I'll just close this topic.