Search code examples
androidandroid-mediaplayerandroid-mediarecorder

Unsolved: Android audio recording using example from Google


I'm learning how to record audio using http://developer.android.com/guide/topics/media/audio-capture.html#example

Everything works fine, but I want to switch:

mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";

to

mFileName = getFilesDir().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";

but I get this error

08-19 15:51:44.212: E/MediaPlayer(6654): error (1, -2147483648)
08-19 15:51:44.212: E/AudioRecordTest(6654): prepare() failed

I tried to log my new code (to make sure that I'm using a valid path).

NOTE:

This works on my Samsung Galaxy, but doesn't work on my Nexus One. I want this to work on 2.x, 3.x, and 4.x

Update: I added a log in startRecording():

mRecorder.setOutputFile(mFileName);
        Log.e("LOG", mFileName);

The output of that log is:

08-22 12:28:40.112: E/LOG(9666): /data/data/com.example.testrecorder/files/audiorecordtest.3gp

Tried logging the exception:

  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)

Solution

  • When you create a new MediaPlayer object, it's not really part of your app, it's part of the system. Because this is true, it can't read files in your app's private directory unless they are WORLD_READABLE. That's why it works with the external directory and not your internal one. Yes, that sounds ridiculous, I agree.

    You should be able to get around this by creating a FileDescriptor and passing it to MediaPlayer that way:

    FileInputStream fis = new FileInputStream(mFileName);
    mPlayer.setDataSource(fis.getFD());
    

    Note: gtkandroid gives a more thorough explanation, which I found through the bug tracker. If this works for you, I'd suggest you upvote his answer on the other question as well.