Воспроизведение файлов ресурсов Android из внутреннего хранилища приводит к тому, что MediaPlayer.prepare выдает IOException - PullRequest
10 голосов
/ 29 января 2011

Мое приложение воспроизводит файлы аудиоресурсов из внутреннего каталога, предназначенного для моего приложения (/ data / data / com ...).Похоже, что файлы загружаются в это место нормально, setDataSource (String path) не выдает никаких исключений, но MediaPlayer.prepare () выдает IOException. Тот же код работает на SD-карте.Почему это происходит?

РЕДАКТИРОВАТЬ:

Давайте предположим, что это код;это проще, чем мой код, и выдает то же исключение:

package com.app.MediaPlayerTest;

public class MediaTest extends Activity {
    MediaPlayer mp;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        DownloadFiles();
        MusicPlay();
    }

    public void DownloadFiles() {
        //Downloads Files
    }

    public void MusicPlay()
    {
            try {
                mp.setDataSource("/data/data/com.app.pronounce/winds.mp3");
            } catch (IllegalArgumentException e1) {
                e1.printStackTrace();
            } catch (IllegalStateException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        try {
            mp.prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mp.setLooping(true);
        mp.start();
    }
}

Что касается трассировки стека:

(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x4001f1a8 self=0xce48
  | sysTid=338 nice=0 sched=0/0 cgrp=bg_non_interactive handle=-1345006528
  | schedstat=( 151460588 425586896 45 )
  at android.os.BinderProxy.transact(Native Method)
  at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:2547)
  at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:76)
  at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854)
  at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851)
  at dalvik.system.NativeStart.main(Native Method)

"Binder Thread #2" prio=5 tid=8 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x40512b30 self=0x156e90
  | sysTid=346 nice=0 sched=0/0 cgrp=default handle=1570912
  | schedstat=( 4357682 930487 3 )
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=7 NATIVE
  | group="main" sCount=1 dsCount=0 obj=0x40512a68 self=0x17f578
  | sysTid=345 nice=0 sched=0/0 cgrp=bg_non_interactive handle=604904
  | schedstat=( 6939806 13372136 3 )
  at dalvik.system.NativeStart.run(Native Method)

"Compiler" daemon prio=5 tid=6 VMWAIT
  | group="system" sCount=1 dsCount=0 obj=0x4050eba8 self=0x938c8
  | sysTid=344 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1099136
  | schedstat=( 4770066 33579300 5 )
  at dalvik.system.NativeStart.run(Native Method)

"JDWP" daemon prio=5 tid=5 VMWAIT
  | group="system" sCount=1 dsCount=0 obj=0x4050eaf8 self=0x10c3c0
  | sysTid=343 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1098624
  | schedstat=( 14899224 33240040 20 )
  at dalvik.system.NativeStart.run(Native Method)

"Signal Catcher" daemon prio=5 tid=4 RUNNABLE
  | group="system" sCount=0 dsCount=0 obj=0x4050ea38 self=0x93570
  | sysTid=342 nice=0 sched=0/0 cgrp=bg_non_interactive handle=588000
  | schedstat=( 24278832 4707632 7 )
  at dalvik.system.NativeStart.run(Native Method)

"GC" daemon prio=5 tid=3 VMWAIT
  | group="system" sCount=1 dsCount=0 obj=0x4050e990 self=0x8f720
  | sysTid=341 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1099336
  | schedstat=( 791698 556969 3 )
  at dalvik.system.NativeStart.run(Native Method)

"HeapWorker" daemon prio=5 tid=2 VMWAIT
  | group="system" sCount=1 dsCount=0 obj=0x4050e8d8 self=0x10c740
  | sysTid=340 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1357728
  | schedstat=( 211702049 225986921 9 )
  at dalvik.system.NativeStart.run(Native Method)

Ответы [ 2 ]

23 голосов
/ 29 марта 2011

MediaPlayer требует, чтобы воспроизводимый файл имел права на чтение для всех.Вы можете просмотреть права доступа к файлу с помощью следующей команды в оболочке adb:

ls -al /data/data/com.mypackage/myfile

Вы, вероятно, увидите «-rw ------», что означает, что только владелец (ваше приложение,не MediaPlayer) имеет права на чтение / запись.

Примечание. Чтобы использовать команду ls без указания файла (во внутренней памяти), ваш телефон должен быть рутован.

Если ваш телефонroot, вы можете добавить права на чтение в оболочке adb с помощью следующей команды:

chmod o+r /data/data/com.mypackage/myfile

Если вам нужно программно изменить эти разрешения (требуется рутированный телефон!), вы можете использовать следующую команду в своем приложениикод:

Runtime.getRuntime().exec("chmod o+r /data/data/com.mypackage/myfile");

или

Runtime.getRuntime().exec("chmod 777 /data/data/com.mypackage/myfile");

В основном это команда linux.См. https://help.ubuntu.com/community/FilePermissions для получения дополнительной информации о chmod.

РЕДАКТИРОВАТЬ: нашел другой простой подход здесь (полезно для тех, у кого нет рутованных телефонов).Поскольку приложению принадлежит файл, оно может создать дескриптор файла и передать его в mediaPlayer.setDataSource ():

FileInputStream fileInputStream = new FileInputStream("/data/data/com.mypackage/myfile");
mediaPlayer.setDataSource(fileInputStream.getFD());

Этот подход полностью исключает проблему с разрешениями.

3 голосов
/ 06 мая 2013

Я знаю, что этот вопрос старше грязи, но он помог мне избавиться от проблемы. Следующее работает отлично:

      FileOutputStream outStream= openFileOutput("movie.mp4", MODE_WORLD_READABLE);

Важным элементом здесь является флаг, читаемый миром.

...