11

私のアプリは、アプリ用に指定された内部ディレクトリ (/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)
4

2 に答える 2

23

MediaPlayer では、再生中のファイルに誰でも読み取り可能なアクセス許可が必要です。ファイルのアクセス許可は、adb シェルで次のコマンドを使用して表示できます。

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

おそらく「-rw------」が表示されます。これは、所有者 (MediaPlayer ではなくアプリ) だけが読み取り/書き込み権限を持っていることを意味します。

注: ファイル (内部メモリ内) を指定せずに ls コマンドを使用するには、電話をルート化する必要があります。

電話がルート化されている場合は、次のコマンドを使用して、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コマンドです。chmod の詳細については、 https://help.ubuntu.com/community/FilePermissionsを参照してください。

編集:ここで別の簡単なアプローチを見つけました(ルート化された電話を持たない人に役立ちます)。アプリケーションはファイルを所有しているため、ファイル記述子を作成し、それを mediaPlayer.setDataSource() に渡すことができます。

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

このアプローチは、パーミッションの問題を完全に回避します。

于 2011-03-28T23:33:17.407 に答える
3

この質問は汚れよりも古いことは知っていますが、問題を洗い流すのに役立ちました. 以下はうまくいきます:

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

誰でも読み取り可能なフラグは、ここで重要な部分です。

于 2013-05-06T02:42:49.653 に答える