Android MediaPlayer文件的完整路径

Pri*_*ime 2 android path media-player

我需要在手机(任何位置)的某个地方获取文件的完整路径并使用MediaPlayer播放.

我听说过使用Android的文件选择器(通过启动一个意图).

在测试代​​码中,我只是将一个资源复制到另一个文件,得到了路径并将其传递给AudioVideoEntry(后面我将展示一个围绕MediaPlayer的非常简单和薄的包装)

这是我写的测试代码:

private String ave_path;
    private String ave_file_name = "my_media_content";
    private InputStream ave_fis;
    private OutputStream ave_fos;
    public void testAudioVideoEntry()
    {
        //get the Activity
        Module_JournalEntry journalentryactivity = getActivity();
        //open an InputStream to a resource file (in this case strokes.mp3)
        ave_fis = journalentryactivity.getResources().openRawResource(module.jakway.JournalEntry.R.raw.strokes);

        //open an OutputStream to a new file
        try {
            ave_fos = journalentryactivity.openFileOutput(ave_file_name, 
                                                Context.MODE_PRIVATE);
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            assertTrue(false);
        }
        catch(Exception e)
        {
            assertTrue(false);
        }

        //copy the data from the resource into
        //the OutputStream
        int data;
        try {
        while((data = ave_fis.read()) != -1)
        {
            ave_fos.write(data);
        }
            assertTrue(true);
        }
        catch(Exception e)
        {
            assertTrue(false);
        }

        //get the full path of the file we wrote to
        ave_path = journalentryactivity.getFileStreamPath(ave_file_name).toString();

        //and construct a new object of AudioVideoEntry with that path
        AudioVideoEntry ave = new AudioVideoEntry(ave_path);

        //register an error listener via MediaPlayer's setOnErrorListener
        ave.setOnErrorListener(new OnErrorListener()
                                {
                                    @Override
                                    public boolean onError(MediaPlayer mp,
                                            int what, int extra) {
                                        Log.e("MEDIAPLAYER ERRORS",
                                        "what: " + what + "  extra: "   + extra);
                                        assertTrue(false);
                                        // TODO Auto-generated method stub
                                        return false;
                                    }
                                });
        ave.prepareMedia();
        ave.playMedia();
        try {
        ave_fis.close();
        ave_fos.close();
        }
        catch(Exception e)
        {
            assertTrue(false);
            e.printStackTrace();
        }
Run Code Online (Sandbox Code Playgroud)

AudioVideoEntry基本上是MediaPlayer的一个瘦包装器,可以保存自己的路径:

public class AudioVideoEntry
{
    private String path_to_audio_file;
    private MediaPlayer mediaplayer;

    /**
     * Initialize the internal MediaPlayer
     * from the String parameter
     * @param set_path_to_audio_file
     */
    public AudioVideoEntry(String set_path_to_audio_file)
    {
        path_to_audio_file = set_path_to_audio_file;
        mediaplayer = new MediaPlayer();
        try {
            mediaplayer.setDataSource(path_to_audio_file);
            mediaplayer.prepare();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public AudioVideoEntry(FileDescriptor fd)
    {

        mediaplayer = new MediaPlayer();
        try {
            mediaplayer.setDataSource(fd);
            mediaplayer.prepare();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }



    /**
     * Begin playing media
     */
    public void prepareMedia()
    {
        try {
            mediaplayer.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     * play media
     * don't forget to prepare() if necessary
     */
    public void playMedia()
    {
        mediaplayer.start();
    }

    /**
     * pause the media
     * can be played later
     */
    public void pauseMedia()
    {
        mediaplayer.pause();
    }

    /**
     * stop media
     */
    public void stopMedia()
    {
        mediaplayer.stop();
    }

    public void setOnErrorListener(OnErrorListener listener)
    {
        mediaplayer.setOnErrorListener(listener);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是来自JUnit测试的logcat输出(测试成功,实际结果 - 如logat所示 - 不是)

02-07 09:40:23.129: ERROR/MediaPlayer(1209): error (1, -2147483648)
02-07 09:40:23.139: WARN/System.err(1209): java.io.IOException: Prepare failed.: status=0x1
02-07 09:40:23.149: WARN/System.err(1209):     at android.media.MediaPlayer.prepare(Native Method)
02-07 09:40:23.149: WARN/System.err(1209):     at module.jakway.JournalEntry.AudioVideoEntry.<init>(AudioVideoEntry.java:39)
02-07 09:40:23.149: WARN/System.err(1209):     at module.jakway.JournalEntry.test.Module_JournalEntryTest.testAudioVideoEntry(Module_JournalEntryTest.java:182)
02-07 09:40:23.149: WARN/System.err(1209):     at java.lang.reflect.Method.invokeNative(Native Method)
02-07 09:40:23.149: WARN/System.err(1209):     at java.lang.reflect.Method.invoke(Method.java:507)
02-07 09:40:23.159: WARN/System.err(1209):     at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:204)
02-07 09:40:23.159: WARN/System.err(1209):     at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:194)
02-07 09:40:23.159: WARN/System.err(1209):     at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:186)
02-07 09:40:23.159: WARN/System.err(1209):     at junit.framework.TestCase.runBare(TestCase.java:127)
02-07 09:40:23.169: WARN/System.err(1209):     at junit.framework.TestResult$1.protect(TestResult.java:106)
02-07 09:40:23.169: WARN/System.err(1209):     at junit.framework.TestResult.runProtected(TestResult.java:124)
02-07 09:40:23.169: WARN/System.err(1209):     at junit.framework.TestResult.run(TestResult.java:109)
02-07 09:40:23.179: WARN/System.err(1209):     at junit.framework.TestCase.run(TestCase.java:118)
02-07 09:40:23.179: WARN/System.err(1209):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
02-07 09:40:23.179: WARN/System.err(1209):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
02-07 09:40:23.179: WARN/System.err(1209):     at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:529)
02-07 09:40:23.189: WARN/System.err(1209):     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
02-07 09:40:23.189: ERROR/MediaPlayer(1209): prepareAsync called in state 0
02-07 09:40:23.189: WARN/System.err(1209): java.lang.IllegalStateException
02-07 09:40:23.189: WARN/System.err(1209):     at android.media.MediaPlayer.prepare(Native Method)
02-07 09:40:23.189: WARN/System.err(1209):     at module.jakway.JournalEntry.AudioVideoEntry.prepareMedia(AudioVideoEntry.java:79)
02-07 09:40:23.199: WARN/System.err(1209):     at module.jakway.JournalEntry.test.Module_JournalEntryTest.testAudioVideoEntry(Module_JournalEntryTest.java:197)
02-07 09:40:23.199: WARN/System.err(1209):     at java.lang.reflect.Method.invokeNative(Native Method)
02-07 09:40:23.199: WARN/System.err(1209):     at java.lang.reflect.Method.invoke(Method.java:507)
02-07 09:40:23.199: WARN/System.err(1209):     at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:204)
02-07 09:40:23.199: WARN/System.err(1209):     at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:194)
02-07 09:40:23.199: WARN/System.err(1209):     at android.test.ActivityInstrumentationTestCase2.runTest(ActivityInstrumentationTestCase2.java:186)
02-07 09:40:23.199: WARN/System.err(1209):     at junit.framework.TestCase.runBare(TestCase.java:127)
02-07 09:40:23.199: WARN/System.err(1209):     at junit.framework.TestResult$1.protect(TestResult.java:106)
02-07 09:40:23.199: WARN/System.err(1209):     at junit.framework.TestResult.runProtected(TestResult.java:124)
02-07 09:40:23.199: WARN/System.err(1209):     at junit.framework.TestResult.run(TestResult.java:109)
02-07 09:40:23.199: WARN/System.err(1209):     at junit.framework.TestCase.run(TestCase.java:118)
02-07 09:40:23.199: WARN/System.err(1209):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
02-07 09:40:23.199: WARN/System.err(1209):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
02-07 09:40:23.199: WARN/System.err(1209):     at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:529)
02-07 09:40:23.199: WARN/System.err(1209):     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)
02-07 09:40:23.199: ERROR/MediaPlayer(1209): start called in state 0
02-07 09:40:23.199: ERROR/MediaPlayer(1209): error (-38, 0)
Run Code Online (Sandbox Code Playgroud)

编辑:为什么MediaPlayer失败?

谢谢!dragonwrenn

typ*_*.pl 11

在AudioVideoEntry.prepareMedia()方法中第二次调用MediaPlayer.prepare()(已经在AudioVideoEntry ctor中调用过一次)很容易被发现,就像其他人注意到的那样.

找到的更难的错误是第一个错误.

我用Ogg文件进行测试.

第一条线索来自android-platform中的 davidsparks回复(最后一个)- G1上的Ogg

只要文件具有.ogg扩展名,就应该使用内置音乐播放器.我们依赖文件扩展名,因为媒体扫描程序没有集中的文件识别器.

第二个线索来自[android-developers] Re:关于MediaPlayer的文件权限

由于Android安全模型,MediaPlayer没有root访问权限.它可以访问SD卡,但无法访问私有应用程序目录.

您的应用可以通过打开文件并使用setDataSource(FileDescriptor fd)方法将文件描述符传递给MediaPlayer,明确授予MediaPlayer对安全文件的临时访问权限.

如果查看输出流的绝对路径,您会看到它位于/data/data应用程序包名称目录下的目录中.

请原谅时间戳 - 我向后工作以获取在OS2.1update1(API7)模拟器上显示的数据.

你的代码有:

String ave_file_name = "my_media_content";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_PRIVATE);
Run Code Online (Sandbox Code Playgroud)

DDMS显示:

02-10 05:10:28.253: WARN/MediaPlayer(1992): info/warning (1, 26)
02-10 05:10:28.253: ERROR/PlayerDriver(31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
02-10 05:10:28.253: ERROR/MediaPlayer(1992): error (1, -4)
02-10 05:10:28.274: WARN/PlayerDriver(31): PVMFInfoErrorHandlingComplete
Run Code Online (Sandbox Code Playgroud)

如果我们改变JUST该文件MODE_WORLD_READABLE:

String ave_file_name = "my_media_content";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_WORLD_READABLE);
Run Code Online (Sandbox Code Playgroud)

DDMS没有改进:

02-10 05:08:28.543: WARN/MediaPlayer(1900): info/warning (1, 26)
02-10 05:08:28.553: ERROR/PlayerDriver(31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
02-10 05:08:28.553: ERROR/MediaPlayer(1900): error (1, -4)
02-10 05:08:28.563: WARN/PlayerDriver(31): PVMFInfoErrorHandlingComplete
Run Code Online (Sandbox Code Playgroud)

如果我们改变JUST文件扩展名ogg:

String ave_file_name = "my_media_content.ogg";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_PRIVATE);
Run Code Online (Sandbox Code Playgroud)

我们得到了DDMS输出的变化:

02-10 04:59:30.153: ERROR/MediaPlayerService(31):   error: -2
02-10 04:59:30.163: ERROR/MediaPlayer(1603): Unable to to create media player
Run Code Online (Sandbox Code Playgroud)

但是当我们把两者结合起来时:

String ave_file_name = "my_media_content.ogg";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_WORLD_READABLE);
Run Code Online (Sandbox Code Playgroud)

DDMS显示没有错误.