Android文件夹管理器源码实现
Posted Jimmy.li
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android文件夹管理器源码实现相关的知识,希望对你有一定的参考价值。
一、资源管理器介绍
现在在一些移动终端上面都会有自带的资源管理器,其实其并非是android系统自带,而是手机产商与app开发商的合作而导致融合,借助第三方的开发软件预装在出厂的手机,是新时代下的另一个霸王条款,还不能自行删除,十分麻烦。
背景铺垫完毕,由于十分讨厌这种不公平的手段,为此自行写一个实现文件资源管理器,功能基本上实现,实用不美观,不喜勿喷!
二、实现函数详解
1、显示文件列表
/**
* 扫描显示文件列表
* @param path
*/
private void showFileDir(String path) {
mFileName = new ArrayList<String>();
mFilePath = new ArrayList<String>();
File file = new File(path);
File[] files = file.listFiles();
//如果当前目录不是根目录
if (!ROOT_PATH.equals(path)) {
mFileName.add("@1");
mFilePath.add(ROOT_PATH);
mFileName.add("@2");
mFilePath.add(file.getParent());
}
//添加所有文件
for (File f : files) {
mFileName.add(f.getName());
mFilePath.add(f.getPath());
}
this.setListAdapter(new MyAdapter(this, mFileName, mFilePath));
}
2、Item点击事件
/**
* 点击事件
* @param l
* @param v
* @param position
* @param id
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
String path = mFilePath.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("Message")
.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);
}
3、对文件进行重命名
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();
}
4、对文件进行删除
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();
}
5、打开文件
//打开文件
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 = getMIMEType(file);
intent.setDataAndType(Uri.fromFile(file), type);
startActivity(intent);
}
6、onCreateOptionsMenu重写,实现新建文件夹
public static void createMkdir(String folderPath) {
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdir();
}
}
三、实现步骤
1、activity_main.xml,主界面布局,最重要的既是ListView浏览方式。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context="example.com.filemanager.MainActivity">
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
2、file.xml,Item的布局方式。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageView"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:textSize="20sp"/>
</LinearLayout>
3、rename_dialog.xml,自定义Dialog方式。
<?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">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
4、MainActivity.java,主Activity,所有事项函数。
package example.com.filemanager;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends ListActivity {
private static final String ROOT_PATH = "/";
//存储文件名称
private ArrayList<String> mFileName = null;
//存储文件路径
private ArrayList<String> mFilePath = null;
//重命名布局xml文件显示dialog
private View view;
private EditText editText;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//显示文件列表
showFileDir(ROOT_PATH);
}
/**
* 扫描显示文件列表
* @param path
*/
private void showFileDir(String path) {
mFileName = new ArrayList<String>();
mFilePath = new ArrayList<String>();
File file = new File(path);
File[] files = file.listFiles();
//如果当前目录不是根目录
if (!ROOT_PATH.equals(path)) {
mFileName.add("@1");
mFilePath.add(ROOT_PATH);
mFileName.add("@2");
mFilePath.add(file.getParent());
}
//添加所有文件
for (File f : files) {
mFileName.add(f.getName());
mFilePath.add(f.getPath());
}
this.setListAdapter(new MyAdapter(this, mFileName, mFilePath));
}
/**
* 点击事件
* @param l
* @param v
* @param position
* @param id
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
String path = mFilePath.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("Message")
.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);
}
//对文件进行增删改
private void fileHandle(final File file) {
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@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 {
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[] menu = {"打开文件", "重命名", "删除文件"};
new AlertDialog.Builder(MainActivity.this)
.setTitle("请选择要进行的操作!")
.setItems(menu, listener)
.setPositiveButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
}).show();
}
//打开文件
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 = getMIMEType(file);
intent.setDataAndType(Uri.fromFile(file), type);
startActivity(intent);
}
//获取文件mimetype
private 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 {
//如果无法直接打开,跳出列表由用户选择
type = "*";
}
type += "/*";
return type;
}
private void displayToast(String message) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
}
public boolean onCreateOptionsMenu(Menu menu) {
//super.getMenuInflater().inflate(R.menu.main_menu, menu);
menu.add(Menu.NONE, Menu.FIRST + 1, 7, "新建")
.setIcon(android.R.drawable.ic_menu_send);
menu.add(Menu.NONE, Menu.FIRST + 2, 3, "取消")
.setIcon(android.R.drawable.ic_menu_edit);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Menu.FIRST + 1:{
final EditText editText = new EditText(MainActivity.this);
new AlertDialog.Builder(MainActivity.this).setTitle("请输入文件名称").setView(editText).setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
String mFileName = editText.getText().toString();
String IMAGES_PATH = Environment.getExternalStorageDirectory() + "/" + mFileName + "/"; //获取根目录
//String IMAGES_PATH = getApplicationContext().getFilesDir().getAbsolutePath() + "/" + mFileName + "/";
createMkdir(IMAGES_PATH);
}
}).setNegativeButton("取消", null).show();
}
break;
case Menu.FIRST + 2:
Toast.makeText(this, "取消", Toast.LENGTH_LONG).show();
break;
}
return false;
}
public static void createMkdir(String folderPath) {
File folder = new File(folderPath);
if (!folder.exists()) {
folder.mkdir();
}
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
finish();
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
}
5、MyAdapter.java
package example.com.filemanager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.File;
import java.util.ArrayList;
/**
* Title: FileManager
* Package example.com.filemanager
* Description: ${TODO}
* author Jimmy.li
* Date: 2016-06-23
* Time: 14:16
* version V1.0
*/
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater;
private Bitmap directory, file;
//存储文件名称
private ArrayList<String> names = null;
//存储文件路径
private ArrayList<String> paths = null;
//参数初始化
public MyAdapter(Context context, ArrayList<String> na, ArrayList<String> pa) {
names = na;
paths = pa;
directory = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
file = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
//缩小图片
directory = small(directory, 0.16f);
file = small(file, 0.1f);
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;
if (null == convertView) {
convertView = inflater.inflate(R.layout.file, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.textView);
holder.image = (ImageView) convertView.findViewById(R.id.imageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
File f = new File(paths.get(position).toString());
if (names.get(position).equals("@1")) {
holder.text.setText("/");
holder.image.setImageBitmap(directory);
} else if (names.get(position).equals("@2")) {
holder.text.setText("..");
holder.image.setImageBitmap(directory);
} else {
holder.text.setText(f.getName());
if (f.isDirectory()) {
holder.image.setImageBitmap(directory);
} else if (f.isFile()) {
holder.image.setImageBitmap(file);
} else {
System.out.println(f.getName());
}
}
return convertView;
}
private class ViewHolder {
private TextView text;
private ImageView image;
}
private Bitmap small(Bitmap map, float num) {
Matrix matrix = new Matrix();
matrix.postScale(num, num);
return Bitmap.createBitmap(map, 0, 0, map.getWidth(), map.getHeight(), matrix, true);
}
}
四、添加权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
五、实现效果图
六、源码下载地址
源码下载地址:http://download.csdn.net/detail/u012721519/9557887
Good luck!
Write by Jimmy.li
以上是关于Android文件夹管理器源码实现的主要内容,如果未能解决你的问题,请参考以下文章
android常用的布局管理器都有哪些,简述各布局管理器的布局特点
Android布局管理器-使用GridLayout表格布局管理器实现简单的用户登录页面