首页 > 代码库 > 我的Android案例—文件管理器

我的Android案例—文件管理器

2015年的Android案例之旅

案例九:文件管理器

知识点:
  1. 功能设计到手机文件、SD卡文件的增删改查功能,目前实现了增查。。
  2. JAVA中对文件的操作
  3. Adapter的使用,无论是SimpleAdapter,还是BaseAdapter
  4. AlertDialog的使用
  5. 还有一些监听事件的使用
涉及文件:

  1.   res->layout->main.xml主界面布局文件
  2. res->layout->item_toolbar.xml适配器布局文件,用于菜单选项
  3. res->layout->list_child.xml  适配器布局文件,用于显示文件列表
  4. res->layout->create_dialog.xml弹出框布局文件,用于创建文件或文件夹
  5. res->layout->search_dialog.xml弹出框布局文件,用于搜索文件       
  6. res-layout->AndroidManifest.xml系统清单文件,主要申明涉及组件,权限
  7. src->package->MainActivity.javajava文件
  8. src->package->FileService.javajava文件
  9. src->package->SearcgBroadCast.javajava文件
main.xml
<!-- 相对布局
	 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background">
    
    <!--文本控件 
    显示当前路径 -->
    <TextView 
        android:id="@+id/show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:singleLine="true"/>
    
    <!-- 列表视图
    显示当前目录的内容 -->
    <ListView 
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/show"
        android:divider="@drawable/line"
        android:cacheColorHint="#000"
        android:layout_marginBottom="70dp"></ListView>
    
    <!-- 网格视图
    显示菜单,创建、修改等菜单项 -->
    <GridView 
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"></GridView>
</RelativeLayout>
item_toolbar.xml
<!-- 菜单适配器布局 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/toolbar_item"
    android:paddingBottom="5dp">
    
    <!-- 图片控件
    	用于显示菜单图片 -->
    <ImageView 
        android:id="@+id/toolbarImage"
        android:layout_width="wrap_content"
        android:layout_height="45dp"
        android:layout_centerHorizontal="true"
        />
    
    <!-- 文本控件
    	用于显示菜单文字 -->
    	<TextView 
    	    android:id="@+id/toolbarTitle"
    	    android:layout_width="wrap_content"
    	    android:layout_height="wrap_content"
    	    android:layout_below="@+id/toolbarImage"
    	    android:layout_centerHorizontal="true"
    	    android:textColor="#fff"/>
</RelativeLayout>
list_child.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="38dp"
    android:layout_gravity="left|center">
    
    <!-- 图标 -->
    <ImageView 
        android:id="@+id/image_list_child" 
        android:layout_width="40dip"
        android:layout_height="40dip"/>"
    <!-- 文本 -->
    <TextView 
        android:id="@+id/text_list_child"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:marqueeRepeatLimit="marquee_forever"/>
</LinearLayout>
create_dialog.xml
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical" >
  <!-- 二选一 -->
<RadioGroup 
	android:id="@+id/radiogroup_create"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content">
	<!-- 创建文件选项 -->
	<RadioButton 
	android:layout_height="wrap_content" 
	android:layout_width="fill_parent" 
	android:text="创建文件夹" 
	android:id="@+id/create_file" />
	<!-- 创建文件夹选项 -->
	<RadioButton 
	android:layout_height="wrap_content" 
	android:layout_width="fill_parent" 
	android:text="创建文件" 
	android:id="@+id/create_folder" />
</RadioGroup>  
	<!-- 文本框,供用户填写文件名称 -->
	<EditText 
	android:layout_height="wrap_content" 
	android:id="@+id/new_filename" 
	android:layout_width="fill_parent" 
	android:hint="请输入名称"
	android:singleLine="true" />	
</LinearLayout>
search_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <!-- 单选列表
    	用于判断搜索范围 -->
    <RadioGroup 
        android:id="@+id/radiogroup_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        
        <!-- 当前路径下搜索 -->
        <RadioButton 
            android:id="@+id/radio_currentpath"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="在当前路径下搜索"/>
        <!-- 在整个目录下搜索 -->
        <RadioButton 
            android:id="@+id/radio_wholepath"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="在整个目录下搜索"/>
    </RadioGroup>
    <EditText 
        android:id="@+id/edit_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入搜索关键字"
        android:singleLine="true"/>
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 系统清单文件
	声明版本号,所包含组件等等 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.filemanager.myfilemanager"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.filemanager.myfilemanager.MainActivity"
            android:label="@string/app_name" >
            <!-- 程序入口声明 -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".FileService">
			<intent-filter>
				<action android:name="com.android.service.FILE_SEARCH_START" />
				<category android:name="android.intent.category.DEFAULT" />
			</intent-filter>
		</service>
    </application>

    <!-- 对SD卡读写的权限 -->
    <uses-permission  android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission  android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>

MainActivity.java
public class MainActivity extends Activity {

	//定义Log标签
	private static final String TAG = "FILEMANAGER";
	private String mAction;
	//声明成员变量
	private TextView show;
	private ListView list;
	private GridView toolbar;
	private boolean isAddBackUp = false;
	// 代表手机或SD卡,1代表手机,2代表SD卡
	private int position = 1;
	//手机起始目录“/” 
	private String mRootPath = java.io.File.separator;
	// SD卡根目录
	private String mSDCard = Environment.getExternalStorageDirectory().toString();
	//用静态变量存储 当前目录路径信息
    public static String mCurrentFilePath = "";
    //文件列表
  	List<String> mFileName;
  	//文件路径列表
  	List<String> mFilePath;
	//菜单项对应的图片和文字
	private int[] toolbarImage = {R.drawable.menu_phone,R.drawable.menu_sdcard,R.drawable.menu_search,
							R.drawable.menu_create,R.drawable.menu_palse,R.drawable.menu_exit};
	private String[] toolbarTitle = {"手机","SD卡","搜索","创建","黏贴","退出"};
	//显示搜索的区域  1:当前路径  2:整个目录
	private int mRadioChecked;
	//搜索内容
	private String keyWords;
	
	//BroadCastReceiver的标识
	public static final String KEYWORD_BROADCAST = "com.filemanager.file.KEYWORD_BROADCAST";
	//标识是否取消搜索
	public static boolean isComeBackFromNotification = false;
	//标识创建文件还是创建文件夹	1标识文件,2标识文件夹
	private static int mChecked;
	private String mNewFolderName = "";
	private File mCreateFile;
	
	//黏贴文件的新和旧路径
	private String mOldFilePath = "";
	private String mNewFilePath = "";
	private boolean isCopy = false;
	private String mCopyFileName;
	
	//程序创建
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Log.i(TAG, "test------ FILEMANAGER is oncreate");
		//初始化菜单视图
		initGridViewData();
		//初始化菜单监听器
		initToolbarListener();
		show = (TextView)findViewById(R.id.show);
		//一开始程序的时候加载手机目录下的文件列表
		initFileListInfo(mRootPath);
		//初始化列表监听事件
		initListListener();
		
		
	}
	
	/**
	 * @param	初始化菜单视图
	 */
	private void initGridViewData(){
		toolbar = (GridView)this.findViewById(R.id.toolbar);
		//设置背景图片
		toolbar.setBackgroundResource(R.drawable.menu_background);
		//设置点击时的背景图片
		toolbar.setSelector(R.drawable.menu_item_selected);
		//设置列数
		toolbar.setNumColumns(6);
		//设置居中对齐
		toolbar.setGravity(Gravity.CENTER);
		 //设置水平,垂直间距为10
		toolbar.setVerticalSpacing(10);
		toolbar.setHorizontalSpacing(10);
		//添加适配器
		toolbar.setAdapter(getToolbarAdapter(toolbarTitle,toolbarImage));
	}
	
	/**
	 * @param	菜单适配器
	 * @return
	 */
	private SimpleAdapter getToolbarAdapter(String[] toolbarTitle,int[] toolbarImage){
		ArrayList<HashMap<String,Object>> mData = http://www.mamicode.com/new ArrayList>();>
FileService.java
/**
 * @param	用于后台搜索文件
 * @author Administrator
 *
 */
public class FileService extends Service{
	private Looper mLooper;
	private FileHandler mFileHandler;
	private ArrayList<String> mFileName = null;
	private ArrayList<String> mFilePaths = null;
	public static final String FILE_SEARCH_COMPLETED = "com.filemanager.file.FILE_SEARCH_COMPLETED";
	public static final String FILE_NOTIFICATION = "com.filemanager.file.FILE_NOTIFICATION";	
	private int m = -1;
	public NotificationManager mNF;
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	//创建服务
	@Override
	public void onCreate() {
		super.onCreate();
		//新建处理线程
		HandlerThread mHT = new HandlerThread("FileService",HandlerThread.NORM_PRIORITY);
		mHT.start();
		mLooper = mHT.getLooper();
		mFileHandler = new FileHandler(mLooper);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		//取消通知
		mNF.cancel(R.string.app_name);
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onStart(Intent intent, int startId){
		super.onStart(intent, startId);
		mFileName = new ArrayList<String>();
		mFilePaths = new ArrayList<String>();
		mFileHandler.sendEmptyMessage(0);
		//发出通知表明正在进行搜索
		fileSearchNotification();
	}
	
	class FileHandler extends Handler{		
		public FileHandler(Looper looper){
			super(looper);
		}		
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			//在指定范围搜索
			initFileArray(new File(SearcgBroadCast.mServiceSearchPath));
			//当用户点击了取消搜索则不发生广播
			if(!MainActivity.isComeBackFromNotification == true){
				Intent intent = new Intent(FILE_SEARCH_COMPLETED);
				intent.putStringArrayListExtra("mFileNameList", mFileName);
				intent.putStringArrayListExtra("mFilePathsList", mFilePaths);
				//搜索完毕之后携带数据并发送广播
				sendBroadcast(intent);
			}
		}	
	}
	
    /**具体做搜索事件的可回调函数*/
    private void initFileArray(File file){
    	Log.d("FileService", "currentArray is "+file.getPath());
    	//只能遍历可读的文件夹,否则会报错
    	if(file.canRead()){
    		File[] mFileArray = file.listFiles();
        	for(File currentArray:mFileArray){
        		if(currentArray.getName().indexOf(SearcgBroadCast.mServiceKeyword) != -1){
        			if (m == -1) {
						m++;
						// 返回搜索之前目录
						mFileName.add("BacktoSearchBefore");
						mFilePaths.add(MainActivity.mCurrentFilePath);
					}
        			mFileName.add(currentArray.getName());
        			mFilePaths.add(currentArray.getPath());
        		}
        		//如果是文件夹则回调该方法
        		if(currentArray.exists()&¤tArray.isDirectory()){
        			//如果用户取消了搜索,应该停止搜索的过程
        			if(MainActivity.isComeBackFromNotification == true){
        				return;
        			}
        			initFileArray(currentArray);
        		}
        	}
    	}                                                                                                                                                                                                                                                                                                                                                                                            
    }    
    
    /**通知*/
    private void fileSearchNotification(){
    	Notification mNotification = new Notification(R.drawable.logo,"后台搜索中...",System.currentTimeMillis());
    	Intent intent = new Intent(FILE_NOTIFICATION);
    	//打开notice时的提示内容
    	intent.putExtra("notification", "当通知还存在,说明搜索未完成,可以在这里触发一个事件,当点击通知回到Activity之后,可以弹出一个框,提示是否取消搜索!");
    	PendingIntent mPI = PendingIntent.getBroadcast(this,0,intent,0);
    	mNotification.setLatestEventInfo(this, "在"+SearcgBroadCast.mServiceSearchPath+"下搜索", "搜索关键字为"+SearcgBroadCast.mServiceKeyword+"【点击可取消搜索】", mPI);
    	if(mNF == null){
    		mNF = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    	}
    	mNF.notify(R.string.app_name, mNotification);
    } 
}
SearcgBroadCast.java
public class SearcgBroadCast extends BroadcastReceiver{

	//接收搜索关键字的静态变量
	public static  String mServiceKeyword = "";
	//接收搜索路径的静态变量   
    public static  String mServiceSearchPath = "";
	@Override
	public void onReceive(Context context, Intent intent) {
		//取得intent
		String mAction = intent.getAction();
		if(MainActivity.KEYWORD_BROADCAST.equals(mAction)){
			//取得intent传递过来的信息
			mServiceKeyword = intent.getStringExtra("keyword");
			mServiceSearchPath = intent.getStringExtra("searchpath");
		}
		
	}

}










我的Android案例—文件管理器