从另一个应用程序访问资产?

7
我在我的应用程序中收到很多请求,要求允许使用来自BetterCut / Open Home的自定义图标包。它似乎的工作方式是安装BetterCut或Open Home,然后可以从市场上安装大量这些免费图标包。一旦安装了这两个应用程序(和其他应用程序),它们将轮询这些图标包并使用这些图标。
我想知道如何轮询已安装的应用程序以获取可用的资源文件夹。我已经打开了一些图标包并验证了其中有一个资源文件夹,并且其中充满了所有icon png文件。
我已经在这里,其他代码网站,谷歌等地方搜索了很多,但没有找到任何线索。
更新:
根据下面的答案,我编写了一些代码,尝试列出自己项目的资产目录中的文件,但似乎没有起作用。
Resources r = this.getResources();
AssetManager a = r.getAssets();
String[] list = a.list("/");
Log.d("test", "Length of / is "+list.length);
for (String s : list) {
    Log.d("test", s);
}

Log.d("test", "Length of /assets is "+a.list("/assets").length);
Log.d("test", "Length of /assets/ is "+a.list("/assets/").length);
Log.d("test", "Length of /assets/ is "+a.list("/assets/").length);
Log.d("test", "Length of ./assets/ is "+a.list("./assets/").length);
Log.d("test", "Length of ./assets is "+a.list("./assets").length);

这是输出结果:
03-16 12:25:04.591: DEBUG/test(13526): Length of / is 6
03-16 12:25:04.591: DEBUG/test(13526): AndroidManifest.xml
03-16 12:25:04.591: DEBUG/test(13526): META-INF
03-16 12:25:04.591: DEBUG/test(13526): assets
03-16 12:25:04.591: DEBUG/test(13526): classes.dex
03-16 12:25:04.591: DEBUG/test(13526): res
03-16 12:25:04.591: DEBUG/test(13526): resources.arsc
03-16 12:25:04.614: DEBUG/test(13526): Length of /assets is 0
03-16 12:25:04.637: DEBUG/test(13526): Length of /assets/ is 0
03-16 12:25:04.661: DEBUG/test(13526): Length of /assets/ is 0
03-16 12:25:04.692: DEBUG/test(13526): Length of ./assets/ is 0
03-16 12:25:04.716: DEBUG/test(13526): Length of ./assets is 0

更新2,已完成99%:

我发现您可以在不使用文件夹名称的情况下从assets目录中读取内容:

InputStream is = assetManager.open("test.png");

我也尝试在应用程序1中使用应用程序2中的一个资源,该资源的文件夹路径为/asset/icon/image.png:

InputStream is = assetManager.open("icon/image.png");

接下来,我发现您可以在assets中列出目录:

String[] list = assetManager.list("icons");

那也很不错。目前唯一失败的是如何列出基本目录资产。

3个回答

4
为了获取基础的 /assets 文件夹,您需要使用 AssetsManager 列出只带引号的目录:
AssetManager am = this.getAssets();
String[] names = am.list("");

将会列出一些其他文件:图片、声音、webkit,可能还有其他的。您可以忽略这些目录,它们是框架资产目录的一部分。这是引用自groups.google.com

目前,资产管理器将从框架资源中合并资产目录和您自己放置在“assets”中的文件。我们应该改变这种行为(它是旧的资源/本地化模型的一部分),但它不会造成太大的损害,除了你看到更多的文件/目录在自己的资产比你可能期望的要多。当通过您的AssetManager访问时,任何与框架资产中的文件相同的文件都将被使用。

您还可以列出资产目录内的子文件夹,不需要任何斜杠:

String[] names= am.list("subfolder");

请注意,文件名中没有包含"/assets"。 最后,一旦您拥有了文件列表,您可以这样加载它们:
InputStream in = am.open("file.png");

这将在基础资产文件夹中加载文件。或者您可以像这样加载子文件夹中的文件:

InputStream in = am.open("subfolder/file.png");

如果您需要将这些PNG文件加载到位图中,您也可以执行以下操作:
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);

1
这似乎解决了问题,谢谢!有趣的是关于框架资产与资产文件夹合并的引用来自Google员工Hackbod,这个人也没有在这里提供答案。 - Cameron McBride

3

Resources 对象为您提供访问资产的权限。 PackageManager 可以为应用程序提供访问 Resources 的权限。


我意识到应该先学会爬行再学会走路,于是我将一个文件添加到我的项目资产文件夹中,现在我正在尝试使用AssetManager列出它,但似乎在尝试列出资产目录时无法实现。我将在原帖中更新我正在尝试的代码。 - Cameron McBride
1
请查看此链接:https://dev59.com/q0nSa4cB1Zd3GeqPPJKT - CommonsWare
我尝试使用该人准确的“displayFiles”方法并进行打印,以查看列表的长度,除了根文件夹“ / ”之外,所有测试的长度仍为零。我从未得到过列出“ /assets”中文件的列表。我还尝试直接访问资产文件夹中的文件: InputStream is = a.open("/assets/test.png");这会引发一个找不到文件的异常。 - Cameron McBride

1

在深入了解之前,您应该先了解资源和资产的基本概念。 :)

首先,.apk只是一个zip文件,因此如果您想浏览其内容,可以将该文件放在主机计算机上,并使用所有常规zip工具来查看它。

其次,在.apk中有两种主要类型的用户提供的文件:原始资产和结构化资源。

前者只是一组任意文件层次结构,可以使用http://developer.android.com/reference/android/content/res/AssetManager.html#open(java.lang.String)检索

后者由内置工具处理成结构化表格,允许它们根据配置而变化。它们使用资源和相关类进行访问。从.apk检索到的可绘制对象、字符串、颜色和大多数其他类型的数据通常存储为资源,而不是资产。

您可以使用aapt工具查看.apk中的所有资源:aapt dump resources

最后,如果你想从这些.apk文件中读取数据,不妨查看它们的构建信息?这将为您提供有关其结构的许多基本信息。


我不需要访问电脑上的文件。我需要从手机上的应用程序1访问应用程序2中的资产目录。我收到了大量请求,要求添加对市场上免费的BetterCut图标包的支持。因此,我希望用户能够从我的应用程序中选择这些图标(它们存储在资产文件夹中,我已经查看过)。你提到的大多数事情与原始问题并不相关。我不需要构建apk的指南,也不需要从res文件夹中使用Drawables或其他资源来提取图像或在自己的应用程序中使用。 - Cameron McBride

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接