我正在创建一个记录音频的应用程序,只要触摸并保持图像按钮即可。我用以下代码实现了这个目标:
public class MainActivity extends Activity {
MediaRecorder recorder;
MediaPlayer mediaPlayer;
//STORAGE PATHS
String storagePath;
String externalStoragePath;
//FULL OUTPUT PATHS
String externalOutputPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//AUDIO RECORDER
recorder = new MediaRecorder();
recorder.reset();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
externalOutputPath = externalStoragePath + File.separator + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3";
recorder.setOutputFile(externalOutputPath);
}
else
{
storagePath = Environment.getDataDirectory().getAbsolutePath();
recorder.setOutputFile(storagePath + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3");
}
//IMAGE BUTTON ONTOUCHLISTENER
final ImageButton recBtn = (ImageButton) findViewById(R.id.recButton);
recBtn.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
recBtn.setImageResource(R.drawable.record_btn_pressed);
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if (event.getAction() == MotionEvent.ACTION_UP)
{
recBtn.setImageResource(R.drawable.record_btn);
try {
recorder.prepare();
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(STORAGE_SERVICE, "File saved to: " + externalStoragePath + "/Android/data/com.whizzappseasyvoicenotepad/test.3gp");
}
return true;
}
});
} //END OF ONCREATE
现在,在我停止录制之后,我在文件管理器(Android应用程序)中搜索了mp3文件并尝试播放音乐播放器,但它不起作用。它说该文件无法播放。
然后我还尝试在应用程序中添加“测试播放”按钮,尝试使用MediaPlayer播放录制的文件,但它也不起作用。只要按下播放按钮,应用程序就会崩溃。
public void testPlay (View v) throws IllegalArgumentException, SecurityException, IllegalStateException, IOException{
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(externalOutputPath);
mediaPlayer.start();
}
是的,我确实将android:onClick =“testPlay”添加到xml文件
Logcat文件:
07-31 16:51:43.938: E/MediaPlayer(26918): Unable to to create media player
07-31 16:51:43.953: E/AndroidRuntime(26918): FATAL EXCEPTION: main
07-31 16:51:43.953: E/AndroidRuntime(26918): java.lang.IllegalStateException: Could not execute method of the activity
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.view.View$1.onClick(View.java:3633)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.view.View.performClick(View.java:4240)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.view.View$PerformClick.run(View.java:17721)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.os.Handler.handleCallback(Handler.java:730)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.os.Handler.dispatchMessage(Handler.java:92)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.os.Looper.loop(Looper.java:137)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.app.ActivityThread.main(ActivityThread.java:5103)
07-31 16:51:43.953: E/AndroidRuntime(26918): at java.lang.reflect.Method.invokeNative(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918): at java.lang.reflect.Method.invoke(Method.java:525)
07-31 16:51:43.953: E/AndroidRuntime(26918): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
07-31 16:51:43.953: E/AndroidRuntime(26918): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-31 16:51:43.953: E/AndroidRuntime(26918): at dalvik.system.NativeStart.main(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918): Caused by: java.lang.reflect.InvocationTargetException
07-31 16:51:43.953: E/AndroidRuntime(26918): at java.lang.reflect.Method.invokeNative(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918): at java.lang.reflect.Method.invoke(Method.java:525)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.view.View$1.onClick(View.java:3628)
07-31 16:51:43.953: E/AndroidRuntime(26918): ... 11 more
07-31 16:51:43.953: E/AndroidRuntime(26918): Caused by: java.io.IOException: setDataSourceFD failed.: status=0x80000000
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.media.MediaPlayer.setDataSource(Native Method)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:981)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:960)
07-31 16:51:43.953: E/AndroidRuntime(26918): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:918)
07-31 16:51:43.953: E/AndroidRuntime(26918): at com.whizzappseasyvoicenotepad.MainActivity.testPlay(MainActivity.java:99)
07-31 16:51:43.953: E/AndroidRuntime(26918): ... 14 more
权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
答案 0 :(得分:0)
java.lang.IllegalStateException
通常表示manifest.xml中缺少权限
答案 1 :(得分:0)
我正在使用AudioRecord类,并在一个单独的线程中读取流并在我去的时候写文件。
我希望通过提供我正在使用的代码来解决您的问题。祝你好运。
In my Constructor:
bufferSize = AudioRecord.getMinBufferSize(mSampleRate,
mNbChannels, RECORDER_AUDIO_ENCODING);
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
public void start()
{
System.out.println("SoundRecorder JAVA: start");
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
mSampleRate, mNbChannels,
RECORDER_AUDIO_ENCODING, bufferSize);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable()
{
@Override
public void run() {
writeAudioDataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
private void writeAudioDataToFile()
{
byte data[] = new byte[bufferSize];
String filename = mTempPath;
FileOutputStream os = null;
mRecordFile = new File(filename);
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int read = 0;
if (null != os)
{
while (isRecording)
{
read = recorder.read(data, 0, bufferSize);
Log.i("SoundRecord", "read " + read + " bytes. Wrote In file: " + filename);
if (AudioRecord.ERROR_INVALID_OPERATION != read) {
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void stop()
{
if (null != recorder)
{
System.out.println("SoundRecorder JAVA: stop");
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
}
答案 2 :(得分:0)
这是一个用于记录AMR-NB(onClick方法)的代码示例
注意:bitRate,sampleRate,FilePath,fileTyp = 3gp
如果您准备的播放器与您录制的播放器相同,那么您的IO错误应该消失......
if (isRecording) return;
tmpFilNme = "me" +Calendar.getInstance().getTime().toString().hashCode();
view.setKeepScreenOn(true);
File dir = Environment.getExternalStorageDirectory();
File appDir = new File(dir, "PictureComment");
if (!appDir.exists()) appDir.mkdir();
recordFilePath = new File(appDir, tmpFilNme +".3gp").getAbsolutePath();
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setAudioEncodingBitRate(12200);
mRecorder.setAudioSamplingRate(8000); // this is the MIME rate
mRecorder.setOutputFile(recordFilePath);
try {
mRecorder.prepare();
mRecorder.start();
isRecording = true;
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
答案 3 :(得分:0)
我仍然不确定是什么问题,但我认为我停止录制的方式有问题(整个尝试,抓住事情)。我只是重写了整个代码,并将MediaRecorder放在两种不同的方法中。 startRecording()和stopRecording()方法。现在它完美无缺!
的startRecording()
public void startRecording (){
recorder = new MediaRecorder();
recorder.reset();
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
externalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
externalOutputPath = externalStoragePath + File.separator + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3";
recorder.setOutputFile(externalOutputPath);
}
else
{
storagePath = Environment.getDataDirectory().getAbsolutePath();
recorder.setOutputFile(storagePath + "/Android/data/com.whizzappseasyvoicenotepad/test.mp3");
}
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
stopRecording()
public void stopRecording() {
if (null != recorder) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}