我花了很多年的时间试图找出如何获取资源文件的目录(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时返回任何内容,它返回[]
请帮助......我绝望地失去了
答案 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 路径引用它们。输入AssetManager。 AssetManager(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中的文件没有“资源”意义:它们仅包含应用程序要使用的数据。由于它们的位置不依赖于上下文,因此可以通过其路径直接访问。
我希望这会有所帮助。