1.需求分析
1.查找文件功能:可以根据指定的目录名与待查找的文件,在指定目录中进行查找,并返回结果
2..实现文件的拷贝与粘贴功能
3.实现文本类文件(.txt, .java, .ini, .bat, )的预览功能(比如实现对前100行文本在某个小窗口中进行预览)
4.实现文件的重命名功能
5..实现对某个文件夹进行统计功能(如统计文件夹中文件数目)
6.在安卓系统上实现
2.本组课题及本人任务
安卓文件资源管理器
1.实现文本类文件(.txt, .java, .ini, .bat, )的预览功能(比如实现对前100行文本在某个小窗口中进行预览)
2.文件或文件夹重命名
3.在安卓系统上实现
3.总体设计(概要设计)
主要设计为Folder类和Filel类
Folder类
提供绝对路径为参数获取对象
可获得目录的各种信息
并提供格式化size数据的方法
Filel类
直接继承File类,简化设计
提供复制文件或为文件夹的方法
文件和文件夹操作流程图
APP基于安卓API18
主Activiy继承于ListView直接显示根目录
视图使用Listview与继承自BaseAdapter的自定义适配器组合
适配器getview中使用convertView,holder静态类加快UI流畅性
3本人负责的主要功能展示与代码分析
1.实现文本类文件(.txt, .java, .ini, .bat, )的预览功能(比如实现对前100行文本在某个小窗口中进行预览)
2.实现文件的重命名功能
3.在安卓系统上实现
4.测试与改进
使用多线程搜索文件
利用外部应用打开音频,视频,图片文件
删除文件
5附录:完整、可运行代码(不打印,电子版需提供)
MainActivity.java
public class MainActivity extends ListActivity {
private static final String ROOT_PATH = "/";
private static String NOW_PATH;
private ImageButton bt_search;
//存储文件名称
private ArrayList FileName = null;
//存储文件路径
private ArrayList FilePath = null;
//重命名布局xml文件显示dialog
private View view;
private EditText v_filename;
private EditText editText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//显示文件列表
showFileDir(ROOT_PATH);
bt_search = (ImageButton)findViewById(R.id.bt_search);
bt_search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
v_filename = (EditText)findViewById(R.id.filename);
Intent intent = new Intent(MainActivity.this,Search.class);
intent.putExtra("path", NOW_PATH);
intent.putExtra("filename", v_filename.getText().toString());
startActivity(intent);
}
});
//长按事件
getListView().setOnItemLongClickListener(new OnItemLongClickListener(){
public boolean onItemLongClick(AdapterView parent, View view, int position,long id) {
String path = FilePath.get(position);
File file = new File(path);
// 文件存在并可读
if (file.exists() && file.canRead()) {
if (file.isDirectory()) {
//处理目录
dirHandle(file);
} else {
//处理文件
fileHandle(file);
}
}
//没有权限
else {
Resources res = getResources();
new AlertDialog.Builder(MainActivity.this).setTitle("提示")
.setMessage(res.getString(R.string.no_permission))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "没有权限", Toast.LENGTH_SHORT).show();
}
}).show();
}
return true;
}
});
showFileDir(NOW_PATH);
}
/**
* 点击事件
* @param l
* @param v
* @param position
* @param id
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
String path = FilePath.get(position);
File file = new File(path);
// 文件存在并可读
if (file.exists() && file.canRead()) {
if (file.isDirectory()) {
//显示子目录及文件
showFileDir(path);
} else {
//处理文件
fileHandle(file);
}
}
//没有权限
else {
Resources res = getResources();
new AlertDialog.Builder(this).setTitle("提示")
.setMessage(res.getString(R.string.no_permission))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "没有权限", Toast.LENGTH_SHORT).show();
}
}).show();
}
super.onListItemClick(l, v, position, id);
}
/**
* 文件处理
* @param file
*/
private void fileHandle(final File file) {
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@SuppressWarnings("deprecation")
@Override
public void onClick(DialogInterface dialog, int which) {
// 打开文件
if (which == 0) {
openFile(file);
}
//重命名
else if (which == 1) {
LayoutInflater factory = LayoutInflater.from(MainActivity.this);
view = factory.inflate(R.layout.rename_dialog, null);
editText = (EditText) view.findViewById(R.id.editText);
editText.setText(file.getName());
DialogInterface.OnClickListener listener2 = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
String modifyName = editText.getText().toString();
final String fpath = file.getParentFile().getPath();
final File newFile = new File(fpath + "/" + modifyName);
if (newFile.exists()) {
//排除没有修改情况
if (!modifyName.equals(file.getName())) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("注意!")
.setMessage("文件名已存在,是否覆盖?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (file.renameTo(newFile)) {
showFileDir(fpath);
displayToast("重命名成功!");
} else {
displayToast("重命名失败!");
}
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
}
} else {
if (file.renameTo(newFile)) {
showFileDir(fpath);
displayToast("重命名成功!");
} else {
displayToast("重命名失败!");
}
}
}
};
AlertDialog renameDialog = new AlertDialog.Builder(MainActivity.this).create();
renameDialog.setView(view);
renameDialog.setButton("确定", listener2);
renameDialog.setButton2("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
renameDialog.show();
}
//拷贝文件
else if (which == 2){
Intent intent = new Intent(MainActivity.this,Copy.class);
intent.putExtra("soupath", file.getPath());
intent.putExtra("isdel", false);
startActivity(intent);
}
//删除文件
else if (which == 3 ){
Intent intent = new Intent(MainActivity.this,Copy.class);
intent.putExtra("soupath", file.getPath());
intent.putExtra("isdel", true);
startActivity(intent);
showFileDir(ROOT_PATH);
}
else {
new AlertDialog.Builder(MainActivity.this)
.setTitle("注意!")
.setMessage("确定要删除此文件吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (file.delete()) {
//更新文件列表
showFileDir(file.getParent());
displayToast("删除成功!");
} else {
displayToast("删除失败!");
}
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
}
};
//选择文件时,弹出操作选项对话框
String type = MyAdapter.getMIMEType(file);
String[] menu = {"打开文件", "重命名", "拷贝","剪切","删除文件",};
if(type=="text"){
menu[0] = "预览";
}
new AlertDialog.Builder(MainActivity.this)
.setTitle("请选择要进行的操作!")
.setItems(menu, listener)
.setPositiveButton("取消", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
/**
* 扫描显示文件列表
* @param path
*/
private void showFileDir(String path) {
FileName = new ArrayList();
FilePath = new ArrayList();
File file = new File(path);
NOW_PATH = path;
File[] files = file.listFiles();
//如果当前目录不是根目录
if (!ROOT_PATH.equals(path)) {
FileName.add("rot");
FilePath.add(ROOT_PATH);
FileName.add("last");
FilePath.add(file.getParent());
}
//添加所有文件
for (File f : files) {
FileName.add(f.getName());
FilePath.add(f.getPath());
}
this.setListAdapter(new MyAdapter(this, FileName, FilePath));
}
/**
* 文件夹处理
* @param file
*/
public void dirHandle(final File file){
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
if(which == 0){
Intent intent = new Intent(MainActivity.this,Copy.class);
intent.putExtra("soupath", file.getPath());
intent.putExtra("isdel", false);
startActivity(intent);
}
else if (which == 1){
Intent intent = new Intent(MainActivity.this,Copy.class);
intent.putExtra("soupath", file.getPath());
intent.putExtra("isdel", true);
startActivity(intent);
showFileDir(ROOT_PATH);
}
else if (which == 2){
Intent intent = new Intent(MainActivity.this,DirDetail.class);
intent.putExtra("path",file.getPath());
startActivity(intent);
}else {
final Folder folder = new Folder(file.getPath());
new AlertDialog.Builder(MainActivity.this)
.setTitle("注意!")
.setMessage("确定删除文件夹及内部所有文件吗?")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (folder.delete()) {
//更新文件列表
showFileDir(file.getParent());
displayToast("删除成功!");
} else {
displayToast("删除失败!");
}
}
})
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
}
};
String[] menu = {"拷贝","剪切","详情","删除"};
new AlertDialog.Builder(MainActivity.this)
.setTitle("请选择要进行的操作!")
.setItems(menu, listener)
.setPositiveButton("取消", listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}).show();
}
//打开文件
/**
* 打开文件
* @param file
*/
private void openFile(File file) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(android.content.Intent.ACTION_VIEW);
String type = Mydapter.getMIMEType(file);
if(file.isDirectory()){
}
else{
if(type.equals("text")){
intent = new Intent(MainActivity.this,Preview.class);
intent.putExtra("path", file.getPath());
}
else{
type += "/*";
intent.setDataAndType(Uri.fromFile(file), type);
}
}
startActivity(intent);
}
/**
* 显示提示消息
* @param message
*/
private void displayToast(String message) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
/**
* back键监听
*/
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
android.os.Process.killProcess(android.os.Process.myPid());
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
}
MyAdapter.java
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater;
private Bitmap directory, file,text;
//存储文件名称
private ArrayList names = null;
//存储文件路径
private ArrayList paths = null;
//参数初始化
public MyAdapter(Context context, ArrayList na, ArrayList pa) {
names = na;
paths = pa;
directory = BitmapFactory.decodeResource(context.getResources(), R.drawable.dir);
file = BitmapFactory.decodeResource(context.getResources(), R.drawable.file);
text = BitmapFactory.decodeResource(context.getResources(), R.drawable.text);
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return names.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return names.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
//如果缓存convertView为空,则需要创建View
if (null == convertView) {
//根据自定义的Item布局加载布局
convertView = inflater.inflate(R.layout.file, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.listitem);
holder.image = (ImageView) convertView.findViewById(R.id.imageView);
//将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag
convertView.setTag(holder);
} else {
//取出tag
holder = (ViewHolder) convertView.getTag();
}
File f = new File(paths.get(position).toString());
if (names.get(position).equals("rot")) {
holder.text.setText("根目录");
holder.image.setImageBitmap(directory);
} else if (names.get(position).equals("last")) {
holder.text.setText("上一级目录");
holder.image.setImageBitmap(directory);
} else {
holder.text.setText(f.getName());
if (f.isDirectory()) {
holder.image.setImageBitmap(directory);
} else if (f.isFile()) {
if(getMIMEType(f).equals("text")){
holder.image.setImageBitmap(text);
}else{
holder.image.setImageBitmap(file);
}
} else {
System.out.println(f.getName());
}
}
return convertView;
}
/* 使用 ViewHolder 的关键好处是缓存了显示数据的视图(View),加快了 UI 的响应速度。
当我们判断 convertView == null 的时候,如果为空,就会根据设计好的List的Item布局(XML)
来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)
再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。
如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder*/
private class ViewHolder {
private TextView text;
private ImageView image;
}
public static String getMIMEType(File file) {
String type = "";
String name = file.getName();
//文件扩展名
String end = name.substring(name.lastIndexOf(".") + 1, name.length()).toLowerCase();
if (end.equals("m4a") || end.equals("mp3") || end.equals("wav")) {
type = "audio";
} else if (end.equals("mp4") || end.equals("3gp")) {
type = "video";
} else if (end.equals("jpg") || end.equals("png") || end.equals("jpeg") || end.equals("bmp") || end.equals("gif")) {
type = "image";
} else if(end.equals("txt") || end.equals("java") || end.equals("ini") || end.equals("bat")){
type = "text";
}
else {
type = "*";
}
return type;
}
}