很久没有写东西了,鉴于某某同学文件管理器不会,这里简单介绍一下,同时写一个demon,参考了网上别人写的代码,自己也学习学习,研究研究。
首先所谓文件管理器,看起来就是一个列表,列表里面是文件夹或者文件,首先把布局写出来,我想在最上方的左边显示文件的路径,右边显示该路径下的文件个数,其实还是一个遍历文件,然后用列表显示出来的问题。下面是ListVIEw,用来显示文件列表。下面是运行的效果图:
主界面的布局文件如下:
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical" > <relativeLayout androID:ID="@+ID/top" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> <TextVIEw androID:ID="@+ID/path" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_alignParentleft="true" androID:layout_centerVertical="true" androID:textSize="@*androID:dimen/List_item_size" androID:textcolor="@androID:color/white"/> <TextVIEw androID:ID="@+ID/item_count" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:textSize="@*androID:dimen/List_item_size" androID:textcolor="@androID:color/white" androID:layout_alignParentRight="true" androID:layout_centerVertical="true"/> </relativeLayout> <VIEw androID:layout_wIDth="match_parent" androID:layout_height="2dip" androID:background="#09c"/> <linearLayout androID:orIEntation="vertical" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <ListVIEw androID:ID="@+ID/file_List" androID:layout_height="match_parent" androID:layout_wIDth="match_parent" androID:fadingEdge="none" androID:cachecolorHint="@androID:color/transparent"/> </linearLayout></linearLayout>
首先在oncreate方法里面调用一个方法去获取布局文件里面的ID:
@OverrIDe protected voID onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.file_manager); initVIEw(); }
initVIEw之后添加apk的权限,777 表示可读可写可 *** 作。
private voID initVIEw() { mListVIEw = (ListVIEw) findVIEwByID(R.ID.file_List); mPathVIEw = (TextVIEw) findVIEwByID(R.ID.path); mItemCount = (TextVIEw) findVIEwByID(R.ID.item_count); mListVIEw.setonItemClickListener(this); String apkRoot = "chmod 777 " + getPackageCodePath(); RootCommand(apkRoot); file folder = new file("/"); initData(folder); }
修改Root权限的方法:
public static boolean RootCommand (String command) { Process process = null; DataOutputStream os = null; try { process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getoutputStream()); os.writeBytes(command + "\n"); os.writeBytes("exit\n"); os.flush(); process.waitFor(); } catch (Exception e) { return false; } finally { try { if (os != null) { os.close(); } process.destroy(); } catch (Exception e) { e.printstacktrace(); } } return true; }
完了之后我们要获取根目录下面的所有的数据,然后设置到我们的ListVIEw中让它显示出来。
private voID initData(file folder) { boolean isRoot = folder.getParent() == null; mPathVIEw.setText(folder.getabsolutePath()); ArrayList<file> files = new ArrayList<file>(); if (!isRoot) { files.add(folder.getParentfile()); } file[] filterfiles = folder.Listfiles(); mItemCount.setText(filterfiles.length + "项"); if (null != filterfiles && filterfiles.length > 0) { for (file file : filterfiles) { files.add(file); } } mfileAdpter = new filelistadapter(this,files,isRoot); mListVIEw.setAdapter(mfileAdpter); }
首先是获取当前是否是根目录,然后把文件的路径设置给我们要显示的VIEw。
然后用一个ArrayList来装我们目录下的所有的文件或者文件夹。
首先要把这个文件夹的父类装到我们的列表中去,然后把这个文件夹下的子文件都拿到,也装在列表中,然后调用Adapter显示出来。既然说到了Adapter,那就看下Adapter吧。
private class filelistadapter extends BaseAdapter { private Context context; private ArrayList<file> files; private boolean isRoot; private LayoutInflater mInflater; public filelistadapter (Context context,ArrayList<file> files,boolean isRoot) { this.context = context; this.files = files; this.isRoot = isRoot; mInflater = LayoutInflater.from(context); } @OverrIDe public int getCount () { return files.size(); } @OverrIDe public Object getItem (int position) { return files.get(position); } @OverrIDe public long getItemID (int position) { return position; } @OverrIDe public VIEw getVIEw (int position,VIEw convertVIEw,VIEwGroup parent) { VIEwHolder vIEwHolder; if(convertVIEw == null) { vIEwHolder = new VIEwHolder(); convertVIEw = mInflater.inflate(R.layout.file_List_item,null); convertVIEw.setTag(vIEwHolder); vIEwHolder.Title = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_Title); vIEwHolder.type = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_type); vIEwHolder.data = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_date); vIEwHolder.size = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_size); } else { vIEwHolder = (VIEwHolder) convertVIEw.getTag(); } file file = (file) getItem(position); if(position == 0 && !isRoot) { vIEwHolder.Title.setText("返回上一级"); vIEwHolder.data.setVisibility(VIEw.GONE); vIEwHolder.size.setVisibility(VIEw.GONE); vIEwHolder.type.setVisibility(VIEw.GONE); } else { String filename = file.getname(); vIEwHolder.Title.setText(filename); if(file.isDirectory()) { vIEwHolder.size.setText("文件夹"); vIEwHolder.size.setTextcolor(color.RED); vIEwHolder.type.setVisibility(VIEw.GONE); vIEwHolder.data.setVisibility(VIEw.GONE); } else { long fileSize = file.length(); if(fileSize > 1024*1024) { float size = fileSize /(1024f*1024f); vIEwHolder.size.setText(new DecimalFormat("#.00").format(size) + "MB"); } else if(fileSize >= 1024) { float size = fileSize/1024; vIEwHolder.size.setText(new DecimalFormat("#.00").format(size) + "KB"); } else { vIEwHolder.size.setText(fileSize + "B"); } int dot = filename.indexOf('.'); if(dot > -1 && dot < (filename.length() -1)) { vIEwHolder.type.setText(filename.substring(dot + 1) + "文件"); } vIEwHolder.data.setText(new SimpleDateFormat("yyyy/MM/dd HH:mm").format(file.lastModifIEd())); } } return convertVIEw; } class VIEwHolder { private TextVIEw Title; private TextVIEw type; private TextVIEw data; private TextVIEw size; } }
看下adapter的布局文件:
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical" > <TextVIEw androID:ID="@+ID/file_Title" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:textSize="25sp" androID:textcolor="#fff000"/> <linearLayout androID:ID="@+ID/file_info" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content"> <TextVIEw androID:ID="@+ID/file_size" androID:layout_wIDth="0dip" androID:layout_height="wrap_content" androID:textcolor="#ffffcc" androID:layout_weight="1" androID:textSize="18sp"/> <TextVIEw androID:ID="@+ID/file_type" androID:layout_wIDth="0dip" androID:layout_height="wrap_content" androID:textcolor="#ffffcc" androID:layout_weight="1" androID:gravity="right" androID:textSize="18sp"/> <TextVIEw androID:ID="@+ID/file_date" androID:layout_wIDth="0dip" androID:layout_height="wrap_content" androID:textcolor="#ffffff" androID:layout_weight="1" androID:gravity="right" androID:textSize="18sp"/> </linearLayout></linearLayout>
列表的Item项分2行显示,上面一行显示文件名
下面一行分别显示文件大小,文件类型,文件修改时间。
我们可以通过file file = (file) getItem(position);拿到Item项的文件,如果是在第一个并且不再根目录我们就把第一个也就是parentfile显示为:“返回上一级”,下一行的都隐藏掉。
如果不是第一个位置,可以拿到这个文件的一系列信息。
先把String filename = file.getname();文件名拿到,显示出来。
如果这个文件是一个文件夹,就把文件的大小显示为“文件夹”,类型和修改时间隐藏掉。
如果不是一个文件夹, 可以拿到文件的长度long fileSize = file.length();
根据特定的长度显示文件的大小,B, KB, MB, GB等。
然后拿到文件的类型,通过最后一个“.”之后的字符串就是该文件的类型。
通过vIEwHolder.data.setText(new SimpleDateFormat("yyyy/MM/dd HH:mm").format(file.lastModifIEd())); 设置文件的最近修改时间。
然后可以设置每个Item项的点击事件,如下所示:
@OverrIDe public voID onItemClick (AdapterVIEw<?> parent,VIEw vIEw,int position,long ID) { file file = (file) mfileAdpter.getItem(position); if(!file.canRead()) { new AlertDialog.Builder(this).setTitle("提示").setMessage("权限不足").setPositivebutton(androID.R.string.ok,new OnClickListener() { @OverrIDe public voID onClick (DialogInterface dialog,int which) { } }).show(); } else if(file.isDirectory()) { initData(file); } else { openfile(file); } }
如果这个文件不能读,就d出对话框显示“权限不足”。
如果是一个文件夹,就在调用一次显示所有文件的方法:initData(file);把这个文件夹作为参数传递下去。
如果是一个文件,就可以调用打开文件的方法打开这个文件。
如何打开文件呢?
可以根据不同的文件的后缀名找到不同的文件类型:
可以用一个二维数组把一些常用的文件类型封装起来。如下:
private final String[][] MIME_Maptable = { // {后缀名, MIME类型} { ".3gp","vIDeo/3gpp" },{ ".apk","application/vnd.androID.package-archive" },{ ".asf","vIDeo/x-ms-asf" },{ ".avi","vIDeo/x-msvIDeo" },{ ".bin","application/octet-stream" },{ ".bmp","image/bmp" },{ ".c","text/plain" },{ ".class",{ ".conf",{ ".cpp",{ ".doc","application/msword" },{ ".docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document" },{ ".xls","application/vnd.ms-excel" },{ ".xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },{ ".exe",{ ".gif","image/gif" },{ ".gtar","application/x-gtar" },{ ".gz","application/x-gzip" },{ ".h",{ ".htm","text/HTML" },{ ".HTML",{ ".jar","application/java-archive" },{ ".java",{ ".jpeg","image/jpeg" },{ ".jpg",{ ".Js","application/x-JavaScript" },{ ".log",{ ".m3u","audio/x-mpegurl" },{ ".m4a","audio/mp4a-latm" },{ ".m4b",{ ".m4p",{ ".m4u","vIDeo/vnd.mpegurl" },{ ".m4v","vIDeo/x-m4v" },{ ".mov","vIDeo/quicktime" },{ ".mp2","audio/x-mpeg" },{ ".mp3",{ ".mp4","vIDeo/mp4" },{ ".mpc","application/vnd.mpohun.certificate" },{ ".mpe","vIDeo/mpeg" },{ ".mpeg",{ ".mpg",{ ".mpg4",{ ".mpga","audio/mpeg" },{ ".msg","application/vnd.ms-outlook" },{ ".ogg","audio/ogg" },{ ".pdf","application/pdf" },{ ".png","image/png" },{ ".pps","application/vnd.ms-powerpoint" },{ ".ppt",{ ".pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation" },{ ".prop",{ ".rc",{ ".rmvb","audio/x-pn-realaudio" },{ ".rtf","application/rtf" },{ ".sh",{ ".tar","application/x-tar" },{ ".tgz","application/x-compressed" },{ ".txt",{ ".wav","audio/x-wav" },{ ".wma","audio/x-ms-wma" },{ ".wmv","audio/x-ms-wmv" },{ ".wps","application/vnd.ms-works" },{ ".xml",{ ".z","application/x-compress" },{ ".zip","application/x-zip-compressed" },{ "","*/*" } };
分别对应的是后缀名和对应的文件类型。
我们可以根据文件的后缀名拿到文件的MIMEType类型:
private String getMIMEType(file file) { String type = "*/*"; String filename = file.getname(); int dotIndex = filename.indexOf('.'); if(dotIndex < 0) { return type; } String end = filename.substring(dotIndex,filename.length()).tolowerCase(); if(end == "") { return type; } for(int i=0; i<MIME_Maptable.length; i++) { if(end == MIME_Maptable[i][0]) { type = MIME_Maptable[i][1] ; } } return type; }
先遍历后缀名,如果找到,就把对应的类型找到并返回。
拿到了类型,就可以打开这个文件。
用这个intent.setDataAndType(Uri.fromfile(file),type); 打开设置打开文件的类型。
如果type是*/*会d出所有的可供选择的应用程序。
到这里一个简易的文件管理器就成型了。
源代码:
package com.androID.test;import java.io.DataOutputStream;import java.io.file;import java.text.DecimalFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import androID.app.Activity;import androID.app.AlertDialog;import androID.content.Context;import androID.content.DialogInterface;import androID.content.Intent;import androID.content.DialogInterface.OnClickListener;import androID.graphics.color;import androID.net.Uri;import androID.os.Bundle;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.AdapterVIEw;import androID.Widget.AdapterVIEw.OnItemClickListener;import androID.Widget.BaseAdapter;import androID.Widget.ListVIEw;import androID.Widget.TextVIEw;import androID.Widget.Toast;public class fileManager extends Activity implements OnItemClickListener { private ListVIEw mListVIEw; private TextVIEw mPathVIEw; private filelistadapter mfileAdpter; private TextVIEw mItemCount; @OverrIDe protected voID onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.file_manager); initVIEw(); } private voID initVIEw() { mListVIEw = (ListVIEw) findVIEwByID(R.ID.file_List); mPathVIEw = (TextVIEw) findVIEwByID(R.ID.path); mItemCount = (TextVIEw) findVIEwByID(R.ID.item_count); mListVIEw.setonItemClickListener(this); String apkRoot = "chmod 777 " + getPackageCodePath(); RootCommand(apkRoot); file folder = new file("/"); initData(folder); } public static boolean RootCommand (String command) { Process process = null; DataOutputStream os = null; try { process = Runtime.getRuntime().exec("su"); os = new DataOutputStream(process.getoutputStream()); os.writeBytes(command + "\n"); os.writeBytes("exit\n"); os.flush(); process.waitFor(); } catch (Exception e) { return false; } finally { try { if (os != null) { os.close(); } process.destroy(); } catch (Exception e) { e.printstacktrace(); } } return true; } private voID initData(file folder) { boolean isRoot = folder.getParent() == null; mPathVIEw.setText(folder.getabsolutePath()); ArrayList<file> files = new ArrayList<file>(); if (!isRoot) { files.add(folder.getParentfile()); } file[] filterfiles = folder.Listfiles(); mItemCount.setText(filterfiles.length + "项"); if (null != filterfiles && filterfiles.length > 0) { for (file file : filterfiles) { files.add(file); } } mfileAdpter = new filelistadapter(this,isRoot); mListVIEw.setAdapter(mfileAdpter); } private class filelistadapter extends BaseAdapter { private Context context; private ArrayList<file> files; private boolean isRoot; private LayoutInflater mInflater; public filelistadapter (Context context,null); convertVIEw.setTag(vIEwHolder); vIEwHolder.Title = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_Title); vIEwHolder.type = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_type); vIEwHolder.data = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_date); vIEwHolder.size = (TextVIEw) convertVIEw.findVIEwByID(R.ID.file_size); } else { vIEwHolder = (VIEwHolder) convertVIEw.getTag(); } file file = (file) getItem(position); if(position == 0 && !isRoot) { vIEwHolder.Title.setText("返回上一级"); vIEwHolder.data.setVisibility(VIEw.GONE); vIEwHolder.size.setVisibility(VIEw.GONE); vIEwHolder.type.setVisibility(VIEw.GONE); } else { String filename = file.getname(); vIEwHolder.Title.setText(filename); if(file.isDirectory()) { vIEwHolder.size.setText("文件夹"); vIEwHolder.size.setTextcolor(color.RED); vIEwHolder.type.setVisibility(VIEw.GONE); vIEwHolder.data.setVisibility(VIEw.GONE); } else { long fileSize = file.length(); if(fileSize > 1024*1024) { float size = fileSize /(1024f*1024f); vIEwHolder.size.setText(new DecimalFormat("#.00").format(size) + "MB"); } else if(fileSize >= 1024) { float size = fileSize/1024; vIEwHolder.size.setText(new DecimalFormat("#.00").format(size) + "KB"); } else { vIEwHolder.size.setText(fileSize + "B"); } int dot = filename.indexOf('.'); if(dot > -1 && dot < (filename.length() -1)) { vIEwHolder.type.setText(filename.substring(dot + 1) + "文件"); } vIEwHolder.data.setText(new SimpleDateFormat("yyyy/MM/dd HH:mm").format(file.lastModifIEd())); } } return convertVIEw; } class VIEwHolder { private TextVIEw Title; private TextVIEw type; private TextVIEw data; private TextVIEw size; } } @OverrIDe public voID onItemClick (AdapterVIEw<?> parent,int which) { } }).show(); } else if(file.isDirectory()) { initData(file); } else { openfile(file); } } private voID openfile(file file) { Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_VIEW); String type = getMIMEType(file); intent.setDataAndType(Uri.fromfile(file),type); try { startActivity(intent); } catch (Exception e) { Toast.makeText(this,"未知类型,不能打开",Toast.LENGTH_SHORT).show(); } } private String getMIMEType(file file) { String type = "*/*"; String filename = file.getname(); int dotIndex = filename.indexOf('.'); if(dotIndex < 0) { return type; } String end = filename.substring(dotIndex,filename.length()).tolowerCase(); if(end == "") { return type; } for(int i=0; i<MIME_Maptable.length; i++) { if(end == MIME_Maptable[i][0]) { type = MIME_Maptable[i][1] ; } } return type; } private final String[][] MIME_Maptable = { // {后缀名, MIME类型} { ".3gp","*/*" } };}
最后补充一下,布局文件中的dimension是编译到jar包里面去了的,没有jar包的童鞋可以改成自己定义大小。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的android文件管理器用法详解全部内容,希望文章能够帮你解决android文件管理器用法详解所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)