从内部存储Android的播放资源文件造成的MediaPlayer。prepare给IOException异常 [英] Android playing resource files from internal storage causes MediaPlayer.prepare to give IOException

查看:306
本文介绍了从内部存储Android的播放资源文件造成的MediaPlayer。prepare给IOException异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序从播放指定我的应用程序内部目录的音频资源文件(/数据/数据​​/ COM ...)。看来下载的文件到该位置还行,的setDataSource(String path)方法不抛出任何异常,但MediaPlayer的。prepare()抛出IOException.The相同code工作在SD卡上。为什么会出现这种情况?

编辑:

让我们假设这是code;它比我的code简单,它抛出同样的异常:

 包com.app.MediaPlayerTest;

公共类MediaTest延伸活动{
    MediaPlayer的熔点;
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);
        DownloadFiles();
        MusicPlay();
    }

    公共无效DownloadFiles(){
        //下载文件
    }

    公共无效MusicPlay()
    {
            尝试 {
                mp.setDataSource(/数据/数据​​/ com.app.pronounce / winds.mp3);
            }赶上(抛出:IllegalArgumentException E1){
                e1.printStackTrace();
            }赶上(IllegalStateException异常E1){
                e1.printStackTrace();
            }赶上(IOException异常E1){
                e1.printStackTrace();
            }
        尝试 {
            MP prepare()。
        }赶上(IllegalStateException异常E){
            e.printStackTrace();
        }赶上(IOException异常E){
            e.printStackTrace();
        }
        mp.setLooping(真正的);
        mp.start();
    }
}
 

至于堆栈跟踪:

 (互斥:TLL = 0 TSL = 0 TSCL = 0 GHL = 0和黄= 0 hwll = 0)
主PRIO = 5 TID = 1的原生
  |组=主SCOUNT = 1 dsCount = 0的obj = 0x4001f1a8自我= 0xce48
  | sysTid = 338漂亮= 0 sched的= 0/0 CGRP = bg_non_interactive处理= -1345006528
  | schedstat =(151460588 425586896 45)
  在android.os.BinderProxy.transact(本机方法)
  在android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:2547)
  在com.android.internal.os.RuntimeInit $ UncaughtHandler.uncaughtException(RuntimeInit.java:76)
  在java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854)
  在java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851)
  在dalvik.system.NativeStart.main(本机方法)

捆扎线2PRIO = 5 TID = 8 NATIVE
  |组=主SCOUNT = 1 dsCount = 0的obj = 0x40512b30自我= 0x156e90
  | sysTid = 346漂亮= 0 sched的= 0/0 CGRP =默认的手柄= 1570912
  | schedstat =(4357682 930487 3)
  在dalvik.system.NativeStart.run(本机方法)

捆扎线#1PRIO = 5 TID = 7 NATIVE
  |组=主SCOUNT = 1 dsCount = 0的obj = 0x40512a68自我=​​ 0x17f578
  | sysTid = 345漂亮= 0 sched的= 0/0 CGRP = bg_non_interactive手柄= 604904
  | schedstat =(6939806 13372136 3)
  在dalvik.system.NativeStart.run(本机方法)

编译器守护PRIO = 5 TID = 6 VMWAIT
  |组=系统SCOUNT = 1 dsCount = 0的obj = 0x4050eba8自我= 0x938c8
  | sysTid = 344漂亮= 0 sched的= 0/0 CGRP = bg_non_interactive手柄= 1099136
  | schedstat =(4770066 33579300 5)
  在dalvik.system.NativeStart.run(本机方法)

JDWP守护PRIO = 5 TID = 5 VMWAIT
  |组=系统SCOUNT = 1 dsCount = 0的obj = 0x4050eaf8自我= 0x10c3c0
  | sysTid = 343漂亮= 0 sched的= 0/0 CGRP = bg_non_interactive手柄= 1098624
  | schedstat =(14899224 33240040 20)
  在dalvik.system.NativeStart.run(本机方法)

信号守望者守护PRIO = 5 TID = 4 RUNNABLE
  |组=系统SCOUNT = 0 dsCount = 0的obj = 0x4050ea38自我= 0x93570
  | sysTid = 342漂亮= 0 sched的= 0/0 CGRP = bg_non_interactive手柄= 588000
  | schedstat =(24278832 4707632 7)
  在dalvik.system.NativeStart.run(本机方法)

全球契约守护PRIO = 5 TID = 3 VMWAIT
  |组=系统SCOUNT = 1 dsCount = 0的obj = 0x4050e990自我= 0x8f720
  | sysTid = 341漂亮= 0 sched的= 0/0 CGRP = bg_non_interactive手柄= 1099336
  | schedstat =(791698 556969 3)
  在dalvik.system.NativeStart.run(本机方法)

HeapWorker守护PRIO = 5 TID = 2 VMWAIT
  |组=系统SCOUNT = 1 dsCount = 0的obj = 0x4050e8d8自我= 0x10c740
  | sysTid = 340漂亮= 0 sched的= 0/0 CGRP = bg_non_interactive手柄= 1357728
  | schedstat =(211702049 225986921 9)
  在dalvik.system.NativeStart.run(本机方法)
 

解决方案

MediaPlayer的要求,正在播放的文件具有世界可读权限。您可以查看文件的权限,在亚洲开发银行的外壳下面的命令:

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

您可能会看到-rw ------,这意味着,只有所有者(您的应用程序,而不是MediaPlayer的)具有读/写权限。

请注意:您的手机必须植根才能使用ls命令,而无需指定文件(在内存中)

如果您的手机扎根,你可以在亚行外壳加上世界读取权限使用以下命令:

 文件模式Ø+ R /data/data/com.mypackage/myfile
 

如果您需要以编程方式修改这些权限(!需要根植电话),您可以在您的应用程序code。使用以下命令:

 调用Runtime.getRuntime()EXEC(文件模式Ø+ R /data/data/com.mypackage/myfile);
 

 调用Runtime.getRuntime()EXEC(搭配chmod 777 /data/data/com.mypackage/myfile)。
 

这基本上是一个linux命令。请参阅<一href="https://help.ubuntu.com/community/FilePermissions">https://help.ubuntu.com/community/FilePermissions更多有关文件模式。

编辑:找到另一种简单的方法<一href="http://groups.google.com/group/android-developers/browse_thread/thread/5569a88c50dcc043/31d7da67e79689d7?lnk=raot&fwc=1">here (适用于那些没有根植电话)。由于应用程序拥有这个文件,它可以创建一个文件描述符,并传递到mediaPlayer.setDataSource():

 的FileInputStream的FileInputStream =新的FileInputStream(/数据/数据​​/ com.mypackage / MYFILE);
mediaPlayer.setDataSource(fileInputStream.getFD());
 

此方法完全避免了权限问题。

My app plays audio resource files from the internal directory designated for my app (/data/data/com...). It seems to download the files to that location okay, setDataSource(String path) doesn't throw any exceptions, but MediaPlayer.prepare() throws IOException.The same code works on the SD card. Why is this happening?

EDIT:

Let's assume this is the code; it's simpler than my code and it throws the same exception:

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

As for the stack trace:

(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)

解决方案

MediaPlayer requires that the file being played has world-readable permissions. You can view the permissions of the file with the following command in adb shell:

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

You will probably see "-rw------", which means that only the owner (your app, not MediaPlayer) has read/write permissions.

Note: Your phone must be rooted in order to use the ls command without specifying the file (in the internal memory).

If your phone is rooted, you can add world-read permissions in adb shell with the following command:

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

If you need to modify these permissions programmatically (requires rooted phone!), you can use the following command in your app code:

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

or

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

Which is basically a linux command. See https://help.ubuntu.com/community/FilePermissions for more on chmod.

EDIT: Found another simple approach here (useful for those without rooted phones). Since the application owns the file, it can create a file descriptor and pass that to mediaPlayer.setDataSource():

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

This approach avoids the permission issue completely.

这篇关于从内部存储Android的播放资源文件造成的MediaPlayer。prepare给IOException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆