我正在学习如何使用http://developer.android.com/guide/topics/media/audio-capture.html#example
录制音频一切正常,但我想切换:
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
到
mFileName = getFilesDir().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
但我收到此错误
08-19 15:51:44.212: E/MediaPlayer(6654): error (1, -2147483648)
08-19 15:51:44.212: E/AudioRecordTest(6654): prepare() failed
我尝试记录我的新代码(以确保我使用的是有效路径)。
我的三星Galaxy上的有效,但我的Nexus One上无法正常工作。我希望这适用于2.x,3.x和4.x
更新 我在startRecording()中添加了一个日志:
mRecorder.setOutputFile(mFileName);
Log.e("LOG", mFileName);
该日志的输出是:
08-22 12:28:40.112: E/LOG(9666): /data/data/com.example.testrecorder/files/audiorecordtest.3gp
尝试记录异常:
private void startPlaying() {
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed", e);
}
}
08-22 13:08:03.158: E/MediaPlayer(10093): error (1, -2147483648)
08-22 13:08:03.168: E/AudioRecordTest(10093): prepare() failed
08-22 13:08:03.168: E/AudioRecordTest(10093): java.io.IOException: Prepare failed.: status=0x1
08-22 13:08:03.168: E/AudioRecordTest(10093): at android.media.MediaPlayer.prepare(Native Method)
08-22 13:08:03.168: E/AudioRecordTest(10093): at com.example.testrecorder.MainActivity.startPlaying(MainActivity.java:51)
08-22 13:08:03.168: E/AudioRecordTest(10093): at com.example.testrecorder.MainActivity.onPlay(MainActivity.java:41)
08-22 13:08:03.168: E/AudioRecordTest(10093): at com.example.testrecorder.MainActivity.access$1(MainActivity.java:39)
08-22 13:08:03.168: E/AudioRecordTest(10093): at com.example.testrecorder.MainActivity$PlayButton$1.onClick(MainActivity.java:113)
08-22 13:08:03.168: E/AudioRecordTest(10093): at android.view.View.performClick(View.java:2532)
08-22 13:08:03.168: E/AudioRecordTest(10093): at android.view.View$PerformClick.run(View.java:9308)
08-22 13:08:03.168: E/AudioRecordTest(10093): at android.os.Handler.handleCallback(Handler.java:587)
08-22 13:08:03.168: E/AudioRecordTest(10093): at android.os.Handler.dispatchMessage(Handler.java:92)
08-22 13:08:03.168: E/AudioRecordTest(10093): at android.os.Looper.loop(Looper.java:150)
08-22 13:08:03.168: E/AudioRecordTest(10093): at android.app.ActivityThread.main(ActivityThread.java:4333)
08-22 13:08:03.168: E/AudioRecordTest(10093): at java.lang.reflect.Method.invokeNative(Native Method)
08-22 13:08:03.168: E/AudioRecordTest(10093): at java.lang.reflect.Method.invoke(Method.java:507)
08-22 13:08:03.168: E/AudioRecordTest(10093): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-22 13:08:03.168: E/AudioRecordTest(10093): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-22 13:08:03.168: E/AudioRecordTest(10093): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:10)
当你创建一个新的MediaPlayer
对象时,它并不是你的应用程序的一部分,它是系统的一部分。因为这是真的,它不能读取应用程序私有目录中的文件,除非它们是WORLD_READABLE
。这就是为什么它适用于外部目录而不是内部目录。是的,这听起来很荒谬,我同意。
您应该可以通过创建FileDescriptor
并以此方式将其传递给MediaPlayer
来解决此问题:
FileInputStream fis = new FileInputStream(mFileName);
mPlayer.setDataSource(fis.getFD());
注意: gtkandroid 提供a more thorough explanation,我通过bug tracker找到了{{3}}。如果这对你有用,我建议你在另一个问题上回答他的答案。
答案 1 :(得分:0)
因此,使用该代码,我不得不在构造函数之外将文件名的创建移动到onCreate()
。 Context
无效,因此您应该在getFilesDir().getAbsolutePath()
上收到错误消息。
@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);
mFileName = getFilesDir().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
}