Android MediaPlayer полный путь к файлу - PullRequest
2 голосов
/ 07 февраля 2011

Мне нужно получить полный путь к файлу где-нибудь на телефоне (в любом месте) и воспроизвести его с помощью 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();
        }

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);
    }
}

вот вывод logcat из теста JUnit (тесты прошли успешно, фактические результаты - как показывает логат - не были)

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)

Редактировать: почему происходит сбой MediaPlayer?

спасибо! dragonwrenn

Ответы [ 3 ]

11 голосов
/ 10 февраля 2011

Второй вызов MediaPlayer.prepare () (который уже вызывался один раз в ctor AudioVideoEntry) в методе AudioVideoEntry.prepareMedia () легко обнаружить, как заметили другие люди.

Сложнее найти ошибкубыла первая ошибка.

Я использовал для проверки файл Ogg.

Первая подсказка была от ответа davidsparks (последнего) в android-platform - Ogg на G1

Пока файлы имеют расширение .ogg, они должны воспроизводиться со встроенным музыкальным проигрывателем.Мы полагаемся на расширения файлов, потому что не существует централизованного распознавателя файлов для медиа-сканера.

Второй ключ был от [android-developers] Re: Разрешение файла для MediaPlayer

Из-за модели безопасности Android MediaPlayer не имеетправа доступа root.Он может получить доступ к SD-карте, но не может получить доступ к частным каталогам приложений.

Ваше приложение может явно предоставить временный доступ MediaPlayer к защищенным файлам, открыв файл и передав дескриптор файла в MediaPlayer с помощью setDataSource (FileDescriptor fd) метод.

Если вы посмотрите на абсолютный путь выходного потока, вы увидите, что он находится в каталоге /data/data в каталоге с именем пакета приложения.

Извините отметки времени -Я работал в обратном направлении, чтобы получить данные для отображения на эмуляторе OS2.1update1 (API7).

Ваш код имел:

String ave_file_name = "my_media_content";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_PRIVATE);

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

Еслимы изменяем JUST файл на MODE_WORLD_READABLE:

String ave_file_name = "my_media_content";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_WORLD_READABLE);

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

Если мы изменим JUST расширение файлав ogg:

String ave_file_name = "my_media_content.ogg";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_PRIVATE);

Мы получаем изменение в выводе 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

Но когда мы объединяем два :

String ave_file_name = "my_media_content.ogg";

ave_fos = activity.openFileOutput(ave_file_name, Context.MODE_WORLD_READABLE);

DDMS не показывает ошибок.

3 голосов
/ 10 февраля 2011

Некоторые моменты:

  1. Не вызывайте prepare() дважды (один раз в конструкторе, а другой явно).Это может быть одной из причин, по которой выбрасывается IllegalStateException.
  2. Кроме того, файл, который вы пытаетесь воспроизвести внутри приложения?Если так, почему вы пытаетесь создать поток?Если файл уже находится внутри приложения (и в пределах /res/raw, вы можете попытаться сэкономить на использовании prepare(), создав объект медиаплеера, например:

    mediaplayer = new MediaPlayer.create (this, R.raw.resource-name здесь);

Функция создания вызывает prepare() в пределах.
3. Вы также можете попробовать использовать функцию reset(), если естьодин из этапов MediaPlayer завершается неудачно, в результате чего объект MediaPlayer входит в состояние ошибки. Использование reset() вернет его в состояние ожидания.
4. В последний раз, когда я получал это сообщение об ошибке status=0x1, оказалось,что у меня не было правильных прав доступа к файлам (внешнему хранилищу и т. д. в манифесте) и некоторым файлам, помещенным в неправильные папки. Возможно, вы также захотите взглянуть на это.это не работает,
Мы можем попробовать что-то еще.
Шрирам.

0 голосов
/ 10 февраля 2011

Кажется, вы вызываете prepare() дважды, сначала в конструкторе AudioVideoEntry, а затем в методе prepareMedia(), поэтому он дает IllegalStateException.

Если вы читаете внимательно документация вы можете понять диаграмму состояний и почему дает такие исключения.

...