问题描述
我在Record Audio应用程序中遇到了一个大问题,我在该网站上阅读了与该应用程序相关的所有帖子,并尝试了建议的每种解决方案,但没有解决我的问题。我的应用程序可以在所有来自AndroidQ 10.0 (SDK29)和以下版本的Android版本上正常运行,并且此问题仅出现在10.0 + 版本中,尤其是在 SDK30 中>。有谁知道如何解决它,或者对导致此错误的原因有任何想法吗?
以下是日志的打印内容: https://imgur.com/a/xSATHSp
清单: https://imgur.com/a/T6eEGmb
代码(第76行): https://imgur.com/a/lrmlB58
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------
我还在“ 可能出什么问题?”子主题下的 ” java.lang中尝试了其他论坛的其他解决方案。 IllegalStateException “: https://www.grokkingandroid.com/recording-audio-using-androids-mediarecorder-framework/
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------
我的日志例外:
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)
我的活动主要代码:
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);
}
}
解决方法
Android 10或更高版本面临的问题是您cannot access files on the external SD card anymore。您必须先使用Storage Access Framework创建文件,然后将其用作存储的基础,或者仅使用应用程序专用存储。
或者-在这种情况下,恕我直言更好-您使用MediaStore
content provider。有关how to add files to MediaStore的更多详细信息,请参见官方文档。
如果您使用MediaStore
,则可以不再使用setOutputfile()
。与setOutputFileDescriptor()
内容提供商一起使用FileDescriptor
代替MediaStore
。