Android:资源文件

时间:2011-08-06 07:06:50

标签: java android

我花了很多年的时间试图找出如何获取资源文件的目录(res/raw)好几个月......我只是找不到怎么做......

我正在尝试获取res/raw的目录,以便我可以使用listFiles()创建一个包含raw文件夹中所有文件的数组,这样我就可以获取文件名和排序我将使用或不通过名称使用的文件(因为我可以通过R.raw.concat(fileIwantToAccess)访问它们)但我需要能够读取文件夹中的所有文件,以便我可以决定使用哪个

有没有更简单的方式告诉Android,我想要这个文件夹的内容?

顺便说一句,我尝试过使用

String directoryName = Soundboard.this.getFilesDir().getParent();

但它返回路径:/data/data/com.soundboard 它有两个子目录:“lib”和“files”,如果我在创建文件之前将两个目录连接到directoryName,当我使用listFiles();但它不返回null时返回任何内容,它返回[]

请帮助......我绝望地失去了

3 个答案:

答案 0 :(得分:1)

@ Michael,

我们无法对彼此的帖子发表评论,因为我们太新了。欢迎,船上。

要回答您的问题,您可以动态查询哪些音频文件可用。您无法使用/res/raw目录执行此操作。您必须使用/assets目录。

首先,我想澄清/res/raw/assets都是使用应用程序打包文件的合法位置。然而,它们用于不同的目的,并且每个具有不同的意义。那么,每个位置的重要性是什么,以及何时(或为什么)将文件放在每个位置?

好吧,我们先考虑/res/raw位置。将文件放在/res/raw中会使文件成为资源。使用Android,资源意味着非常具体;它不仅仅意味着“可以使用的东西”。相反,资源可能会在运行时具有“可交换”的多个版本。 “活动”版本将取决于应用程序的上下文(环境)。例如,针对不同的区域设置和语言,针对不同的形状因子(屏幕尺寸),针对设备的不同方向,或甚至针对应用的不同视觉主题,可能存在相同“资源”的若干不同版本!

通过资源ID访问资源,资源ID类似于指针;他们间接地提到了不同的变体。例如,我可能会在应用程序中打包3个不同版本的图标,每个版本都适合不同的屏幕密度。但是,在我的源代码中,我没有单独引用每个版本;我只有一个资源ID - 类似R.drawable.icon - 引用“图标”。当设备在高密度屏幕上运行时,R.drawable.icon“指向”高密度版本的图标;在低密度设备上,R.drawable.icon“指向”低密度版本。

现在,用于实际解析资源名称的机制超出了本文的范围。但结果是:每个变体都有不同路径,但资源ID 是所有变体的相同!因此,我们必须仅通过ID来引用资源。我们不能通过路径引用资源,甚至不能列出出来的路径 - 这会破坏资源的目的。我们不应该这样做。我们应该始终知道我们需要哪些资源,我们只知道我们将获得哪种变体我们不关心(至少,我们不应该)。

这就是为什么在查询/res/raw中的资源,甚至到达目录本身时遇到这样的问题。这些功能与资源的概念背道而驰。根据定义,您始终可以提前知道您想要的资源 - 以及随之而来的资源ID。

那么,如果你不知道自己想要什么,那么想知道什么是可用的呢?那么,这就是 / assets 位置的目的。注意 /assets 是资源层次结构的一部分。其中包括/res/raw/assets/assets之间的区别 不是资源

由于放置在/assets中的内容不是资源,因此它们没有资源ID。所以你必须通过他们的路径引用它们。事实上,既然你 不知道/assets文件夹本身的位置,您必须通过 relative 路径引用它们。输入AssetManagerAssetManager(a)知道如何找到应用程序的/assets文件夹,(b)如何列出/assets文件夹下的文件和文件夹,以及(c)如何打开文件和文件夹在/assets文件夹下。要了解如何完成此操作,请查看AssetManager课程的文档,如果您需要进一步的指导,请重新发布。

因此,总结一下:如果您有一个资源文件,则将其放在/res/raw中,并通过它的资源ID访问它。如果文件不是资源,则将其放在/assets文件夹中的某个位置,然后通过其路径访问它。

有关资源的详细信息,请参阅Application Resources

中的Android Developers Guide页面

这会让事情更清楚吗?

答案 1 :(得分:0)

您可以尝试如下:

resId=getResources().getIdentifier(
    "name of your file inside raw folder",
    "raw",
    this.getPackageName()
);

答案 2 :(得分:0)

也许你应该考虑使用资产文件而不是原始资源。

原始资源旨在通过资源ID引用,而不是通过路径引用。例如,如果将文件 foo.txt 放在/res/raw中,则可以通过资源ID R.raw.foo访问该文件。据推测,原始资源仅在编译时知道资源名称时使用。

文件位于/assets,另一方面,不生成资源ID。它们 旨在被路径引用;实际上,您必须使用AssetManager通过其路径访问它们。因此,如果在编译时知道资源/文件的名称,/assets是更好的选择,但“当你看到它时会知道它”。 AssetManager甚至有一种在特定路径列出文件的方法。例如,如果您想要一个文件列表/assets/foo,可以尝试:

try {
    AssetManager am = getAssets();
    String files[] = am.list("foo");
    // process the files
}
catch (IOException ioe) {
    // do something wise
}

现在,扩展AndroidMirza的观点,如果您在编译时知道可能的资源集,但想要在运行时选择性地访问这些资源,那么您可以使用资源名称以动态生成其ID。这就是AndroidMirza的建议。例如,考虑一下:

    // names of resources we actually want to use
    String desiredResources[] = { "foo", "bar" };
    for (String rName : desiredResources) {
        // dynamically generate the resource's ID from its name
        int rID =
            getResources().getIdentifier(rName, "raw",
                this.getPackageName());

        // open the resource using the generated ID
        InputStream rStream = getResources().openRawResource(rID);
    }

总之,请回想一下,资源在Android中具有特殊意义。具体而言,资源用于动态调整应用程序的上下文(本地化,不同的硬件配置文件,特定配置等)。虽然原始资源和资产文件都用于以字节流的形式访问文件,但它们具有不同的意图。放在/ res / raw中的文件旨在成为实际资源:替代版本可能存在于不同的上下文中。由于这些资源可以根据上下文解析为不同的路径,因此可以通过其资源ID间接访问它们。但是,置于/ assets中的文件没有“资源”意义:它们仅包含应用程序要使用的数据。由于它们的位置不依赖于上下文,因此可以通过其路径直接访问。

我希望这会有所帮助。