英文:
MediaRecorder start called in invalid state: 4 || E/AudioRecording: prepare() failed
问题
public class MainActivity extends AppCompatActivity{
// ... (other imports and variable declarations)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recordbtn = (ImageButton)findViewById(R.id.record);
stopbtn = (ImageButton)findViewById(R.id.stopRecord);
playbtn = (ImageButton)findViewById(R.id.play);
stopplay = (ImageButton)findViewById(R.id.stopplay);
pausebtn = (ImageButton)findViewById(R.id.pause);
// ... (other initialization code)
recordbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ... (recording button click logic)
}
});
stopbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ... (stop recording button click logic)
}
});
playbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ... (play button click logic)
}
});
pausebtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ... (pause button click logic)
}
});
stopplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ... (stop playback button click logic)
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
// ... (permission request result handling)
}
public boolean CheckPermissions() {
// ... (permission check logic)
}
private void RequestPermissions() {
// ... (permission request logic)
}
}
Please note that I've removed the comments, URLs, and log information, and provided only the translated Java code related to your MainActivity.
英文:
I'm with a big problem in my Record Audio App, and I read every post related to it in this site, and tryied every solution suggested, but didn't solved my problem. My app works fine in all Android versions from AndroidQ 10.0(SDK29) and bellow, and this problems only appears at version 10.0+, specifically in SDK30. Does anyone knows how to solve it, or maybe, have any idea about what is causing this bug?
<br>
Here is a print of the log: https://imgur.com/a/xSATHSp<br>
The Manifest: https://imgur.com/a/T6eEGmb<br>
The Code(line76): https://imgur.com/a/lrmlB58<br>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------<br>
I also tryied other solutions from another foruns, like this one, in the section "What could go wrong?" at subtopic "java.lang.IllegalStateException": https://www.grokkingandroid.com/recording-audio-using-androids-mediarecorder-framework/<br><br>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------<br><br>
My log exception:
E/AudioRecording: prepare() failed
E/MediaRecorder: start called in an invalid state: 4
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myfetus, PID: 17985
java.lang.IllegalStateException
at android.media.MediaRecorder.start(Native Method)
at com.example.myfetus.MainActivity$1.onClick(MainActivity.java:81)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
<br>My ActivityMain code:
public class MainActivity extends AppCompatActivity{
private ImageButton recordbtn, stopbtn, playbtn, stopplay, pausebtn;
private MediaRecorder mRecorder;
private MediaPlayer mPlayer;
private static final String LOG_TAG = "AudioRecording";
private static String mFileName = null;
public static final int REQUEST_AUDIO_PERMISSION_CODE = 1;
private int buttonState = 0;
private EditText editsenha1;
private TextView test1;
private ImageView editImagem;
private int i=0;
Date createdTime = new Date();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recordbtn = (ImageButton)findViewById(R.id.record);
stopbtn = (ImageButton)findViewById(R.id.stopRecord);
playbtn = (ImageButton)findViewById(R.id.play);
stopplay = (ImageButton)findViewById(R.id.stopplay);
pausebtn = (ImageButton)findViewById(R.id.pause);
stopbtn.setEnabled(false);
playbtn.setEnabled(false);
stopplay.setEnabled(false);
mFileName = (Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "MyFetus" +createdTime + "Audio.m4a").replaceAll(" ", "_").replaceAll(":", "-");
test1 = findViewById(R.id.texto2);
editImagem = findViewById(R.id.imageView4);
recordbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (CheckPermissions()) {
stopbtn.setEnabled(true);
recordbtn.setEnabled(false);
playbtn.setEnabled(false);
stopplay.setEnabled(false);
pausebtn.setEnabled(false);
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setAudioEncodingBitRate(128000);
mRecorder.setAudioSamplingRate(44100);
mRecorder.setOutputFile(mFileName);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
Toast.makeText(getApplicationContext(), "Recording Started", Toast.LENGTH_LONG).show();
test1.setText("Gravando...");
test1.setTextColor(Color.parseColor("#0af263"));
} else {
RequestPermissions();
}
recordbtn.setVisibility(View.INVISIBLE);
stopbtn.setVisibility(View.VISIBLE);
}
});
stopbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopbtn.setEnabled(false);
recordbtn.setEnabled(true);
playbtn.setEnabled(true);
stopplay.setEnabled(true);
pausebtn.setEnabled(true);
mRecorder.stop();
mRecorder.release();
mRecorder = null;
Toast.makeText(getApplicationContext(), "Recording Stopped", Toast.LENGTH_LONG).show();
test1.setText("Aperte para gravar");
test1.setTextColor(Color.parseColor("#FADCEE"));
stopbtn.setVisibility(View.INVISIBLE);
recordbtn.setVisibility(View.VISIBLE);
}
});
playbtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopbtn.setEnabled(false);
recordbtn.setEnabled(true);
playbtn.setEnabled(false);
stopplay.setEnabled(true);
pausebtn.setEnabled(true);
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
Toast.makeText(getApplicationContext(), "Recording Started Playing", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
});
pausebtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mPlayer!=null){
mPlayer.pause();
stopbtn.setEnabled(true);
recordbtn.setEnabled(true);
playbtn.setEnabled(true);
stopplay.setEnabled(true);
pausebtn.setEnabled(false);
Toast.makeText(getApplicationContext(),"Audio Paused", Toast.LENGTH_SHORT).show();}
}
});
stopplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPlayer.release();
mPlayer = null;
stopbtn.setEnabled(false);
recordbtn.setEnabled(true);
playbtn.setEnabled(true);
stopplay.setEnabled(false);
pausebtn.setEnabled(true);
Toast.makeText(getApplicationContext(),"Audio Stopped", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_AUDIO_PERMISSION_CODE:
if (grantResults.length> 0) {
boolean permissionToRecord = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean permissionToStore = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (permissionToRecord && permissionToStore) {
Toast.makeText(getApplicationContext(), "Permission Granted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),"Permission Denied",Toast.LENGTH_LONG).show();
}
}
break;
}
}
public boolean CheckPermissions() {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), RECORD_AUDIO);
return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
}
private void RequestPermissions() {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{RECORD_AUDIO, WRITE_EXTERNAL_STORAGE}, REQUEST_AUDIO_PERMISSION_CODE);
}
}
答案1
得分: 1
你在 Android 10 及更高版本上遇到的问题是,你无法再访问外部 SD 卡上的文件。你必须使用存储访问框架(Storage Access Framework)先创建一个文件,然后将其用作存储的基础,或者仅使用应用程序的私有存储空间。
或者,在我个人看来,更好的方法是使用 MediaStore
内容提供程序。有关如何向 MediaStore 添加文件的更多详细信息,请参阅官方文档中的如何向 MediaStore 添加文件。
如果你使用 MediaStore
,就不能再使用 setOutputFile()
了。请改为使用从 MediaStore
内容提供程序获取的 FileDescriptor
,并使用 setOutputFileDescriptor()
。
英文:
The problem you are facing with Android 10 upwards is, that you cannot access files on the external SD card anymore. You have to use either the Storage Access Framework to create a file first and then use it as a base for storing, or you only use app private storage.
Or - IMHO better in this case - you use the MediaStore
content provider. See the official docs for more details about how to add files to MediaStore.
If you use MediaStore
you canot use setOutputfile()
anymore. Use setOutputFileDescriptor()
instead with the FileDescriptor
you can get from the MediaStore
content provider.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论