Android 原始资源文件的使用详解
程序员文章站
2023-11-20 17:31:58
背景知识介绍与其他平台的应用程序一样,android中的应用程序也会使用各种资源,比如图片,字串等,会把它们放入源码的相应文件夹下面,如/res/drawable, /re...
背景知识介绍
与其他平台的应用程序一样,android中的应用程序也会使用各种资源,比如图片,字串等,会把它们放入源码的相应文件夹下面,如/res/drawable, /res/xml, /res/values/, /res/raw, /res/layout和/assets。android也支持并鼓励开发者把ui相关的布局和元素,用xml资源来实现。总结起来,android中支持的资源有:
•颜色值 /res/values 以resources为root的xml文件,定义形式为<color name>value</color>
•字串 /res/values 以resources为root的xml文件<string name>value</string>
•图片 /res/drawable 直接放入,支持9 patch可*拉伸
•图片的颜色 /res/values 以resources为root的xml文件,定义形式为<drawable name>value</drawable>
•单位资源 /res/values 以resources为root的xml文件<dimen name>value</dimen>
•菜单 /res/menu 以menuo为root的xml文件
•布局 /res/layout 这个就是gui的布局和元素
•风格和主题 /res/values 以resources为root的xml文件<style name>value</style>
•动画 /res/anim 有二种:一个是帧动画(frame animation),也就是连续变换图片以animation-list为root的xml文件;另外一种就是补间动画(tweened animation),它对应于api中的animation和animationset,有translate、scale、rotate、alpha四种,以set为root来定义,这个set就相当于animationset
再说下目录:
•/res/anim 用于存放动画
•/res/drawable 存放图片,或等同于图片的资源如shape,或selector
•/res/menu 存放menu
•/res/values 存放修饰性资源:字串,颜色,单位,风格和主题
•/res/layout 存放ui布局和元素
•/res/raw 存放运行时想使用的原始文件
•/assets 存放运行时想使用的原始文件
除了原始文件目录/res/raw和/assets以外,其他的资源在编译的时候都会被第三方软件aapt进行处理,一个是把图片和xml文件进行处理,例如把xml编译成为二进制形式;另外处理的目的就是生成r.java文件,这个文件是访问资源时必须要用到的。
/res目录下面的所有文件都会映射到r.java文件中,以整数id的形式被标识,相同类型的资源被一个内部类来封装,一个r.java的文件类似于这样:
/* auto-generated file. do not modify.
*
* this class was automatically generated by the
* aapt tool from the resource data it found. it
* should not be modified by hand.
*/
package com.android.explorer;
public final class r {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class id {
public static final int action=0x7f060004;
public static final int description_panel=0x7f060001;
public static final int fileinfo=0x7f060003;
public static final int filename=0x7f060002;
public static final int linearlayout_test_1=0x7f060005;
public static final int linearlayout_test_2=0x7f060006;
public static final int linearlayout_test_3=0x7f060007;
public static final int thumbnail=0x7f060000;
}
public static final class layout {
public static final int fileant_list_item=0x7f030000;
public static final int linearlayout_test=0x7f030001;
}
public static final class raw {
public static final int androidmanifest=0x7f040000;
}
public static final class string {
public static final int app_name=0x7f050001;
public static final int hello=0x7f050000;
}
}
从这个r.java就可看出在/res中定义或提供资源时的注意事项:
1. 同一个类型,或同一文件夹下面的资源不可以使用相同的文件名,也就是说不能用文件扩展名来区别不同的文件,因为r.java中只保留资源的文件名而不管扩展名,所以如果有二个图片一个是icon.png另一个是icon.jpg,那么在r.java中只会有一个r.drawable.icon。另外一个则会无法访问到。
2. 资源文件的名字必须符合java变量的命名规则,且不能有大写,只能是'[a-z][0-9]._',否则会有编译错误,因为r.java中的变量id要与资源中的文件一一对应,也就是说用资源文件名来作为id的变量名,所以一定要符合java变量的命名规则,另外它还不能有大写。
3. 除了sdk支持的folder外,不能再有子folder,虽不会有编译错误,但是子folder会被完全忽略,如在/res/layout下在建一个子folder activity(/res/layout/acitivity/, 那么你在生成的r.java中是看不到activity和其内的内容的。
4. 对于资源文件的大小有限制,最好不要让单个文件大于1m,这是sdk文档说明的限制,但具体的我没有进行试验(据说2.2版本以后的可支持到10m,不知道是真的还是假的)
5. 所有/res下面的资源都能通过resources()并提供id来访问。
使用原始资源
对于大多数资源在编译时会对文件内容进行特殊处理,以方便apk在运行时访问。 如果想要运行时使用未经处理的原始资源,可以把资源文件放在/res/raw和/assets目录下面,这二个目录的主要区别在于:
1. /res/raw中的文件会被映射到r.java中
虽然/res/raw中的文件不会被aapt处理成为二进制,但是它的文件还是被映射到r.java中,以方便以资源id形式来访问
2. 子目录结构
如上面所述,/res/raw中虽可以有子目录,但是在程序运行时是无法访问到的,因为/res下面的所有非法子目录在r.java中都是看不到的。而且这些子目录和文件都不会被编译进入apk中,解压apk文件后也看不到/res/raw下面去找了。
而/assets是允许有子目录的,并且完全可以访问到,并且会被打包进apk,解压apk后,这些文件仍然存在并且与源码包中的一样。
3. 访问方式
/res/raw下面的文件(子文件夹是访问不到的了)的访问方式是通过resources,并且必须提供资源的id
inputstream in = context.getresources().openrawresource(r.id.filename);
所以为什么子文件夹无法访问,因为没有id啊。
而/assets则要通过assetmanager来访问。下面着重讲解如何访问/assets下面的资源文件。
通过assetmanager来访问/assets下面的原始资源文件
1. 文件的读取方式
用assetmanager.open(string filename)来打开一个文件,这是一组重载方法,还有其他参数可以设置打开模式等,可以参考文档
这里的filename是相对于/assets的路径,比如:
inputstream in = massetmanager.open("hello.txt"); // '/assets/hello.txt'
inputstream in2 = massetmanager.open("config/ui.txt"); // '/assets/config/ui.txt'
2. 文件夹处理 --- 如何遍历/assets
可以看到如果想要访问/assets下面的文件,必须要知道文件名和相对于/assets的路径。所以,如果你不预先知道其下面有什么的时候又该如何处理呢?那就需要列出它下面所有的文件,然后再选取我们需要的,所以新的问题来了,如何列出/assets下面所有的文件呢?
assetmanager提供了一个列出/assets下某个路径下面的方法:
public finalstring[]list(string path)
since: api level 1
return a string array of all the assets at the given path.
parameters
path a relative path within the assets, i.e., "docs/home.html".
returns
•string[] array of strings, one for each asset. these file names are relative to 'path'. you can open the file by concatenating 'path' and a name in the returned string (via file) and passing that to open().
其实这个文档写的有问题,list()是列出一个文件夹下面的文件,所以应该传入一个文件夹路径而非文档中的"docs/home.html"。
还有一个最大的问题就是如何列出根目录/assets下面的内容,因为只有知道了根目录下面的东西,才能去相对的子目录去找东西,所以这是个必须最先解决的问题。
其实文档没有说的太明白这个方法到底如何使用,也就是说这个string参数到底如何传。猜想着根目录为/assets,所以尝试了以下:
massetmanager.list("."); // returns array size is 0
massetmanager.list("/"); // returns [androidmanifest.xml, meta-inf, assets, classes.dex, res, resources.arsc] // don't worry, u can see these files though, no way to access them
massetmanager.list("/assets"); // returns array size is 0
//google了一下,找到了正解:
massetmanager.list(""); // returns stuff in /assets
然后再根据所列出的子项去递归遍历子文件,直到找到所有的文件为止。
常见的问题
1. 资源文件只能以inputstream方式来获取
如果想操作文件怎么办,如果想要用文件uri怎么办。光靠api当然不行,它只给你inputstream,也就是说它是只读的。可行的办法就是读取文件然后写入一个临时文件中,再对临时文件进行想要的文件操作。可以在内部存储或外部存储上面用context提供的接口来创建文件,详细的请参考<android开发笔记之: 数据存储方式详解>。java牛人可能想要用java本身的能力:
file file.createtempfile(string prefix, string suffix);
file file.createtempfile(string prefix, string suffix, file path);
这也是可以的,但要考虑android系统的特性,也就是说所写的路径是否有权限。比如对于第一个方法,用的是"java.io.tmpdir"这个在android当中就是"/sdcard",所以当没有sd卡时这个方法必抛异常。
2. 所有资源文件都是只读的,运行时无法更改
因为,程序运行时是把apk动态解析加载到内存中,也就是说,apk是不会有变化的,它是无法被改变的。
3. 所有的资源文件夹/res和/assets也都是只读的,不可写入
如上面所说,apk是在编译后是无法再改变的了。
实例
下面是一个实例,可以递归式的遍历/assets下面所有的文件夹和文件
package com.android.explorer;
import java.io.bufferedinputstream;
import java.io.bufferedoutputstream;
import java.io.file;
import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import android.app.listactivity;
import android.content.context;
import android.content.intent;
import android.content.res.assetmanager;
import android.net.uri;
import android.os.bundle;
import android.os.environment;
import android.text.textutils;
import android.util.log;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.webkit.mimetypemap;
import android.widget.baseadapter;
import android.widget.imagebutton;
import android.widget.linearlayout;
import android.widget.textview;
/*
* explore all stuff in /assets and perform actions specified by users.
*/
public class fileantactivity extends listactivity {
private static final string tag = "fileantactivity";
private assetmanager massetmanager;
private static final string extra_current_directory = "current_directory";
private static final string extra_parent = "parent_directory";
public static final string fileant_view = "com.android.fileant.view";
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
intent intent = getintent();
string current = null;
string parent = null;
if (intent != null && intent.hasextra(extra_current_directory)) {
current = intent.getstringextra(extra_current_directory);
}
if (current == null) {
current = "";
}
if (intent != null && intent.hasextra(extra_parent)) {
parent = intent.getstringextra(extra_parent);
}
if (parent == null) {
parent = "";
}
massetmanager = getassets();
if (textutils.isempty(parent)) {
settitle("/assets");
} else {
settitle(parent);
}
try {
// list all the stuff in /assets
if (!textutils.isempty(parent)) {
current = parent + file.separator + current;
}
log.e(tag, "current: '" + current + "'");
string[] stuff = massetmanager.list(current);
setlistadapter(new fileantadapter(this, stuff, current));
} catch (ioexception e) {
e.printstacktrace();
}
}
private class fileantadapter extends baseadapter {
private context mcontext;
private string[] mentries;
private string mparentdirectory;
public fileantadapter(context context, string[] data, string parent) {
mcontext = context;
this.mentries = data;
mparentdirectory = parent;
}
public int getcount() {
return mentries.length;
}
public object getitem(int position) {
return mentries[position];
}
public long getitemid(int position) {
return (long) position;
}
public view getview(final int position, view item, viewgroup parent) {
layoutinflater factory = layoutinflater.from(mcontext);
if (item == null) {
item = factory.inflate(r.layout.fileant_list_item, null);
textview filename = (textview) item.findviewbyid(r.id.filename);
textview fileinfo = (textview) item.findviewbyid(r.id.fileinfo);
imagebutton action = (imagebutton) item.findviewbyid(r.id.action);
final string entry = mentries[position];
filename.settext(entry);
boolean isdir = isdirectory(entry);
if (isdir) {
fileinfo.settext("click to view folder");
action.setvisibility(view.gone);
item.setclickable(true);
item.setonclicklistener(new view.onclicklistener() {
public void onclick(view view) {
intent intent = new intent(fileant_view);
intent.putextra(extra_current_directory, entry);
intent.putextra(extra_parent, mparentdirectory);
startactivity(intent);
}
});
} else {
final string type =
mimetypemap.getsingleton().getmimetypefromextension(getextension(entry));
fileinfo.settext(type);
item.setclickable(false);
action.setonclicklistener(new view.onclicklistener() {
public void onclick(view view) {
string filepath = entry;
if (!textutils.isempty(mparentdirectory)) {
filepath = mparentdirectory + file.separator + filepath;
}
bufferedinputstream in = new bufferedinputstream(mmanager.open(filepath));
// do whatever you like with this input stream
}
});
}
}
return item;
}
}
/**
* test whether an entry is a file or directory based on the rule:
* file: has extension *.*, or starts with ".", which is a hidden files in unix/linux,
* otherwise, it is a directory
* @param filename
* @return
*/
private boolean isdirectory(string filename) {
return !(filename.startswith(".") || (filename.lastindexof(".") != -1));
}
private string getextension(string filename) {
int index = filename.lastindexof(".");
if (index == -1) {
return "";
}
return filename.substring(index + 1, filename.length()).tolowercase();
}
}
与其他平台的应用程序一样,android中的应用程序也会使用各种资源,比如图片,字串等,会把它们放入源码的相应文件夹下面,如/res/drawable, /res/xml, /res/values/, /res/raw, /res/layout和/assets。android也支持并鼓励开发者把ui相关的布局和元素,用xml资源来实现。总结起来,android中支持的资源有:
•颜色值 /res/values 以resources为root的xml文件,定义形式为<color name>value</color>
•字串 /res/values 以resources为root的xml文件<string name>value</string>
•图片 /res/drawable 直接放入,支持9 patch可*拉伸
•图片的颜色 /res/values 以resources为root的xml文件,定义形式为<drawable name>value</drawable>
•单位资源 /res/values 以resources为root的xml文件<dimen name>value</dimen>
•菜单 /res/menu 以menuo为root的xml文件
•布局 /res/layout 这个就是gui的布局和元素
•风格和主题 /res/values 以resources为root的xml文件<style name>value</style>
•动画 /res/anim 有二种:一个是帧动画(frame animation),也就是连续变换图片以animation-list为root的xml文件;另外一种就是补间动画(tweened animation),它对应于api中的animation和animationset,有translate、scale、rotate、alpha四种,以set为root来定义,这个set就相当于animationset
再说下目录:
•/res/anim 用于存放动画
•/res/drawable 存放图片,或等同于图片的资源如shape,或selector
•/res/menu 存放menu
•/res/values 存放修饰性资源:字串,颜色,单位,风格和主题
•/res/layout 存放ui布局和元素
•/res/raw 存放运行时想使用的原始文件
•/assets 存放运行时想使用的原始文件
除了原始文件目录/res/raw和/assets以外,其他的资源在编译的时候都会被第三方软件aapt进行处理,一个是把图片和xml文件进行处理,例如把xml编译成为二进制形式;另外处理的目的就是生成r.java文件,这个文件是访问资源时必须要用到的。
/res目录下面的所有文件都会映射到r.java文件中,以整数id的形式被标识,相同类型的资源被一个内部类来封装,一个r.java的文件类似于这样:
复制代码 代码如下:
/* auto-generated file. do not modify.
*
* this class was automatically generated by the
* aapt tool from the resource data it found. it
* should not be modified by hand.
*/
package com.android.explorer;
public final class r {
public static final class attr {
}
public static final class drawable {
public static final int icon=0x7f020000;
}
public static final class id {
public static final int action=0x7f060004;
public static final int description_panel=0x7f060001;
public static final int fileinfo=0x7f060003;
public static final int filename=0x7f060002;
public static final int linearlayout_test_1=0x7f060005;
public static final int linearlayout_test_2=0x7f060006;
public static final int linearlayout_test_3=0x7f060007;
public static final int thumbnail=0x7f060000;
}
public static final class layout {
public static final int fileant_list_item=0x7f030000;
public static final int linearlayout_test=0x7f030001;
}
public static final class raw {
public static final int androidmanifest=0x7f040000;
}
public static final class string {
public static final int app_name=0x7f050001;
public static final int hello=0x7f050000;
}
}
从这个r.java就可看出在/res中定义或提供资源时的注意事项:
1. 同一个类型,或同一文件夹下面的资源不可以使用相同的文件名,也就是说不能用文件扩展名来区别不同的文件,因为r.java中只保留资源的文件名而不管扩展名,所以如果有二个图片一个是icon.png另一个是icon.jpg,那么在r.java中只会有一个r.drawable.icon。另外一个则会无法访问到。
2. 资源文件的名字必须符合java变量的命名规则,且不能有大写,只能是'[a-z][0-9]._',否则会有编译错误,因为r.java中的变量id要与资源中的文件一一对应,也就是说用资源文件名来作为id的变量名,所以一定要符合java变量的命名规则,另外它还不能有大写。
3. 除了sdk支持的folder外,不能再有子folder,虽不会有编译错误,但是子folder会被完全忽略,如在/res/layout下在建一个子folder activity(/res/layout/acitivity/, 那么你在生成的r.java中是看不到activity和其内的内容的。
4. 对于资源文件的大小有限制,最好不要让单个文件大于1m,这是sdk文档说明的限制,但具体的我没有进行试验(据说2.2版本以后的可支持到10m,不知道是真的还是假的)
5. 所有/res下面的资源都能通过resources()并提供id来访问。
使用原始资源
对于大多数资源在编译时会对文件内容进行特殊处理,以方便apk在运行时访问。 如果想要运行时使用未经处理的原始资源,可以把资源文件放在/res/raw和/assets目录下面,这二个目录的主要区别在于:
1. /res/raw中的文件会被映射到r.java中
虽然/res/raw中的文件不会被aapt处理成为二进制,但是它的文件还是被映射到r.java中,以方便以资源id形式来访问
2. 子目录结构
如上面所述,/res/raw中虽可以有子目录,但是在程序运行时是无法访问到的,因为/res下面的所有非法子目录在r.java中都是看不到的。而且这些子目录和文件都不会被编译进入apk中,解压apk文件后也看不到/res/raw下面去找了。
而/assets是允许有子目录的,并且完全可以访问到,并且会被打包进apk,解压apk后,这些文件仍然存在并且与源码包中的一样。
3. 访问方式
/res/raw下面的文件(子文件夹是访问不到的了)的访问方式是通过resources,并且必须提供资源的id
复制代码 代码如下:
inputstream in = context.getresources().openrawresource(r.id.filename);
所以为什么子文件夹无法访问,因为没有id啊。
而/assets则要通过assetmanager来访问。下面着重讲解如何访问/assets下面的资源文件。
通过assetmanager来访问/assets下面的原始资源文件
1. 文件的读取方式
用assetmanager.open(string filename)来打开一个文件,这是一组重载方法,还有其他参数可以设置打开模式等,可以参考文档
这里的filename是相对于/assets的路径,比如:
复制代码 代码如下:
inputstream in = massetmanager.open("hello.txt"); // '/assets/hello.txt'
inputstream in2 = massetmanager.open("config/ui.txt"); // '/assets/config/ui.txt'
2. 文件夹处理 --- 如何遍历/assets
可以看到如果想要访问/assets下面的文件,必须要知道文件名和相对于/assets的路径。所以,如果你不预先知道其下面有什么的时候又该如何处理呢?那就需要列出它下面所有的文件,然后再选取我们需要的,所以新的问题来了,如何列出/assets下面所有的文件呢?
assetmanager提供了一个列出/assets下某个路径下面的方法:
复制代码 代码如下:
public finalstring[]list(string path)
since: api level 1
return a string array of all the assets at the given path.
parameters
path a relative path within the assets, i.e., "docs/home.html".
returns
•string[] array of strings, one for each asset. these file names are relative to 'path'. you can open the file by concatenating 'path' and a name in the returned string (via file) and passing that to open().
其实这个文档写的有问题,list()是列出一个文件夹下面的文件,所以应该传入一个文件夹路径而非文档中的"docs/home.html"。
还有一个最大的问题就是如何列出根目录/assets下面的内容,因为只有知道了根目录下面的东西,才能去相对的子目录去找东西,所以这是个必须最先解决的问题。
其实文档没有说的太明白这个方法到底如何使用,也就是说这个string参数到底如何传。猜想着根目录为/assets,所以尝试了以下:
复制代码 代码如下:
massetmanager.list("."); // returns array size is 0
massetmanager.list("/"); // returns [androidmanifest.xml, meta-inf, assets, classes.dex, res, resources.arsc] // don't worry, u can see these files though, no way to access them
massetmanager.list("/assets"); // returns array size is 0
//google了一下,找到了正解:
massetmanager.list(""); // returns stuff in /assets
然后再根据所列出的子项去递归遍历子文件,直到找到所有的文件为止。
常见的问题
1. 资源文件只能以inputstream方式来获取
如果想操作文件怎么办,如果想要用文件uri怎么办。光靠api当然不行,它只给你inputstream,也就是说它是只读的。可行的办法就是读取文件然后写入一个临时文件中,再对临时文件进行想要的文件操作。可以在内部存储或外部存储上面用context提供的接口来创建文件,详细的请参考<android开发笔记之: 数据存储方式详解>。java牛人可能想要用java本身的能力:
复制代码 代码如下:
file file.createtempfile(string prefix, string suffix);
file file.createtempfile(string prefix, string suffix, file path);
这也是可以的,但要考虑android系统的特性,也就是说所写的路径是否有权限。比如对于第一个方法,用的是"java.io.tmpdir"这个在android当中就是"/sdcard",所以当没有sd卡时这个方法必抛异常。
2. 所有资源文件都是只读的,运行时无法更改
因为,程序运行时是把apk动态解析加载到内存中,也就是说,apk是不会有变化的,它是无法被改变的。
3. 所有的资源文件夹/res和/assets也都是只读的,不可写入
如上面所说,apk是在编译后是无法再改变的了。
实例
下面是一个实例,可以递归式的遍历/assets下面所有的文件夹和文件
复制代码 代码如下:
package com.android.explorer;
import java.io.bufferedinputstream;
import java.io.bufferedoutputstream;
import java.io.file;
import java.io.filenotfoundexception;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.inputstream;
import android.app.listactivity;
import android.content.context;
import android.content.intent;
import android.content.res.assetmanager;
import android.net.uri;
import android.os.bundle;
import android.os.environment;
import android.text.textutils;
import android.util.log;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.webkit.mimetypemap;
import android.widget.baseadapter;
import android.widget.imagebutton;
import android.widget.linearlayout;
import android.widget.textview;
/*
* explore all stuff in /assets and perform actions specified by users.
*/
public class fileantactivity extends listactivity {
private static final string tag = "fileantactivity";
private assetmanager massetmanager;
private static final string extra_current_directory = "current_directory";
private static final string extra_parent = "parent_directory";
public static final string fileant_view = "com.android.fileant.view";
@override
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
intent intent = getintent();
string current = null;
string parent = null;
if (intent != null && intent.hasextra(extra_current_directory)) {
current = intent.getstringextra(extra_current_directory);
}
if (current == null) {
current = "";
}
if (intent != null && intent.hasextra(extra_parent)) {
parent = intent.getstringextra(extra_parent);
}
if (parent == null) {
parent = "";
}
massetmanager = getassets();
if (textutils.isempty(parent)) {
settitle("/assets");
} else {
settitle(parent);
}
try {
// list all the stuff in /assets
if (!textutils.isempty(parent)) {
current = parent + file.separator + current;
}
log.e(tag, "current: '" + current + "'");
string[] stuff = massetmanager.list(current);
setlistadapter(new fileantadapter(this, stuff, current));
} catch (ioexception e) {
e.printstacktrace();
}
}
private class fileantadapter extends baseadapter {
private context mcontext;
private string[] mentries;
private string mparentdirectory;
public fileantadapter(context context, string[] data, string parent) {
mcontext = context;
this.mentries = data;
mparentdirectory = parent;
}
public int getcount() {
return mentries.length;
}
public object getitem(int position) {
return mentries[position];
}
public long getitemid(int position) {
return (long) position;
}
public view getview(final int position, view item, viewgroup parent) {
layoutinflater factory = layoutinflater.from(mcontext);
if (item == null) {
item = factory.inflate(r.layout.fileant_list_item, null);
textview filename = (textview) item.findviewbyid(r.id.filename);
textview fileinfo = (textview) item.findviewbyid(r.id.fileinfo);
imagebutton action = (imagebutton) item.findviewbyid(r.id.action);
final string entry = mentries[position];
filename.settext(entry);
boolean isdir = isdirectory(entry);
if (isdir) {
fileinfo.settext("click to view folder");
action.setvisibility(view.gone);
item.setclickable(true);
item.setonclicklistener(new view.onclicklistener() {
public void onclick(view view) {
intent intent = new intent(fileant_view);
intent.putextra(extra_current_directory, entry);
intent.putextra(extra_parent, mparentdirectory);
startactivity(intent);
}
});
} else {
final string type =
mimetypemap.getsingleton().getmimetypefromextension(getextension(entry));
fileinfo.settext(type);
item.setclickable(false);
action.setonclicklistener(new view.onclicklistener() {
public void onclick(view view) {
string filepath = entry;
if (!textutils.isempty(mparentdirectory)) {
filepath = mparentdirectory + file.separator + filepath;
}
bufferedinputstream in = new bufferedinputstream(mmanager.open(filepath));
// do whatever you like with this input stream
}
});
}
}
return item;
}
}
/**
* test whether an entry is a file or directory based on the rule:
* file: has extension *.*, or starts with ".", which is a hidden files in unix/linux,
* otherwise, it is a directory
* @param filename
* @return
*/
private boolean isdirectory(string filename) {
return !(filename.startswith(".") || (filename.lastindexof(".") != -1));
}
private string getextension(string filename) {
int index = filename.lastindexof(".");
if (index == -1) {
return "";
}
return filename.substring(index + 1, filename.length()).tolowercase();
}
}