我的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.java java文件
  8. src->package->FileService.java java文件
  9. src->package->SearcgBroadCast.java java文件
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 = new ArrayList<HashMap<String,Object>>();
		for(int i = 0; i < toolbarTitle.length; i++){
			HashMap<String,Object> map = new HashMap<String,Object>();
			//将“image”映射成图片资源
			map.put("image", toolbarImage[i]);
			//将“title”映射成标题
			map.put("title", toolbarTitle[i]);
			mData.add(map);
		}
		//新建简单适配器,设置适配器的布局文件,映射关系
		return new SimpleAdapter(this, mData, R.layout.item_toolbar, new String[]{"image","title"}, new int[]{R.id.toolbarImage,R.id.toolbarTitle});
	}
	
	/**
	 * @param	初始化监听事件
	 */
	private void initToolbarListener(){
		toolbar.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View v, int code,
					long arg3) {
				switch(code){
					//手机文件目录
					case 0:
						position = 1;
						initFileListInfo(mRootPath);
						break;
					//SD卡目录
					case 1:
						position = 2;
						initFileListInfo(mSDCard);
						break;
					//搜索
					case 2:
						searchDilalog();
						break;
					//创建
					case 3:
						createFolder();
						break;
					//黏贴
					case 4:
						palseFile();
						break;
					//退出
					case 5:
						MainActivity.this.finish();
						break;
				}
				
			}
		});
	}
	
	/**
	 * @param	初始化目录内容
	 * @param path
	 */
	private void initFileListInfo(String filePath){
		isAddBackUp = false;
		mCurrentFilePath = filePath;
		//显示当前路径
		show.setText(filePath);
		//文件列表
		mFileName = new ArrayList<String>();
		//文件路径列表
		mFilePath = new ArrayList<String>();
		File mFile = new File(filePath);
		//遍历出该文件夹路径下的所有文件/文件夹
		File[] allFiles = mFile.listFiles();
		//只要当前路径不是手机根目录或者是sd卡根目录则显示“返回根目录”和“返回上一级”
		if(position == 1&&!mCurrentFilePath.equals(mRootPath)){
    		initAddBackUp(filePath,mRootPath);
    	}else if(position == 2&&!mCurrentFilePath.equals(mSDCard)){
        	initAddBackUp(filePath,mSDCard);
    	}
		/*将所有文件信息添加到集合中*/
		for(File mCurrentFile:allFiles){
    		mFileName.add(mCurrentFile.getName());
    		mFilePath.add(mCurrentFile.getPath());
    	}
		//适配数据
		list = (ListView)this.findViewById(R.id.list);
		list.setAdapter(new FileAdapter(MainActivity.this,mFileName,mFilePath));
	}

	 /*
	  * 根据点击“手机”还是“SD卡”来加“返回根目录”和“返回上一级”
	  */
    private void initAddBackUp(String filePath,String phone_sdcard){
    	
    	if(!filePath.equals(phone_sdcard)){
    		/*列表项的第一项设置为返回根目录*/
    		mFileName.add("BacktoRoot");
    		mFilePath.add(phone_sdcard);
    		/*列表项的第二项设置为返回上一级*/
    		mFileName.add("BacktoUp");
    		//回到当前目录的父目录即回到上级
    		mFilePath.add(new File(filePath).getParent());
    		//将添加返回按键标识位置为true
    		isAddBackUp = true;
    	}
    	
    }
    
    //自定义Adapter内部类
    class FileAdapter extends BaseAdapter{
    	//返回键,各种格式的文件的图标
    	private Bitmap mBackRoot;
    	private Bitmap mBackUp;
    	private Bitmap mImage;
    	private Bitmap mAudio;
    	private Bitmap mRar;
    	private Bitmap mVideo;
    	private Bitmap mFolder;
    	private Bitmap mApk;
    	private Bitmap mOthers;
    	private Bitmap mTxt;
    	private Bitmap mWeb;
    	
    	private Context mContext;
    	//文件名列表
    	private List<String> mFileNameList;
    	//文件对应的路径列表
    	private List<String> mFilePathList;
    	
    	public FileAdapter(Context context,List<String> fileName,List<String> filePath){
    		mContext = context;
    		mFileNameList = fileName;
    		mFilePathList = filePath;
    		//初始化图片资源
    		//返回到根目录
    		mBackRoot = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_root);
    		//返回到上一级目录
    		mBackUp = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_up);
    		//图片文件对应的icon
    		mImage = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.image);
    		//音频文件对应的icon
    		mAudio = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.audio);
    		//视频文件对应的icon
    		mVideo = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.video);
    		//可执行文件对应的icon
    		mApk = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.apk);
    		//文本文档对应的icon
    		mTxt = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.txt);
    		//其他类型文件对应的icon
    		mOthers = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.others);
    		//文件夹对应的icon
    		mFolder = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.folder);
    		//zip文件对应的icon
    		mRar = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.zip_icon);
    		//网页文件对应的icon
    		mWeb = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.web_browser);
    	}

    	//获得文件的总数
		@Override
		public int getCount() {
			return mFilePathList.size();
		}

		//获得当前位置对应的文件名
		@Override
		public Object getItem(int position) {
			return mFileNameList.get(position);
		}

		//获得当前的位置
		@Override
		public long getItemId(int position) {
			return position;
		}

		//获得视图
		@Override
		public View getView(int position, View convertView, ViewGroup viewgroup) {
			ViewHolder viewHolder = null;
			if (convertView == null) {
				viewHolder = new ViewHolder();
				LayoutInflater mLI = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				//初始化列表元素界面
				convertView = mLI.inflate(R.layout.list_child, null);
				//获取列表布局界面元素
				viewHolder.mIV = (ImageView)convertView.findViewById(R.id.image_list_child);
				viewHolder.mTV = (TextView)convertView.findViewById(R.id.text_list_child);
				//将每一行的元素集合设置成标签
				convertView.setTag(viewHolder);
			} else {
				//获取视图标签
				viewHolder = (ViewHolder) convertView.getTag();
			}
			File mFile = new File(mFilePathList.get(position).toString());
			//如果
			if(mFileNameList.get(position).toString().equals("BacktoRoot")){
				//添加返回根目录的按钮
				viewHolder.mIV.setImageBitmap(mBackRoot);
				viewHolder.mTV.setText("返回根目录");
			}else if(mFileNameList.get(position).toString().equals("BacktoUp")){
				//添加返回上一级菜单的按钮
				viewHolder.mIV.setImageBitmap(mBackUp);
				viewHolder.mTV.setText("返回上一级");
			}else if(mFileNameList.get(position).toString().equals("BacktoSearchBefore")){
				//添加返回搜索之前目录的按钮
				viewHolder.mIV.setImageBitmap(mBackRoot);
				viewHolder.mTV.setText("返回搜索之前目录");
			}else{
				String fileName = mFile.getName();
				viewHolder.mTV.setText(fileName);
				if(mFile.isDirectory()){
					viewHolder.mIV.setImageBitmap(mFolder);
				}else{
			    	String fileEnds = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();//取出文件后缀名并转成小写
			    	if(fileEnds.equals("m4a")||fileEnds.equals("mp3")||fileEnds.equals("mid")||fileEnds.equals("xmf")||fileEnds.equals("ogg")||fileEnds.equals("wav")){
			    		viewHolder.mIV.setImageBitmap(mVideo);
			    	}else if(fileEnds.equals("3gp")||fileEnds.equals("mp4")){
			    		viewHolder.mIV.setImageBitmap(mAudio);
			    	}else if(fileEnds.equals("jpg")||fileEnds.equals("gif")||fileEnds.equals("png")||fileEnds.equals("jpeg")||fileEnds.equals("bmp")){
			    		viewHolder.mIV.setImageBitmap(mImage);
			    	}else if(fileEnds.equals("apk")){
			    		viewHolder.mIV.setImageBitmap(mApk);
			    	}else if(fileEnds.equals("txt")){
			    		viewHolder.mIV.setImageBitmap(mTxt);
			    	}else if(fileEnds.equals("zip")||fileEnds.equals("rar")){
			    		viewHolder.mIV.setImageBitmap(mRar);
			    	}else if(fileEnds.equals("html")||fileEnds.equals("htm")||fileEnds.equals("mht")){
			    		viewHolder.mIV.setImageBitmap(mWeb);
			    	}else {
			    		viewHolder.mIV.setImageBitmap(mOthers);
			    	}
				}				
			}
			return convertView;
		}
		
		
		//用于存储列表每一行元素的图片和文本
		class ViewHolder {
				ImageView mIV;
				TextView mTV;
			}
    	
    }
    
    
    Intent serviceIntent;
    /**
     * @param 搜索
     */
    private void searchDilalog(){
    	//用于确定是在当前目录搜索或者是在整个目录搜索的标志
    	mRadioChecked = 1;
    	//加载布局文件
    	LayoutInflater mLI = LayoutInflater.from(MainActivity.this); 
    	final View mView = mLI.inflate(R.layout.search_dialog, null);
    	//获取单选表对象
    	RadioGroup rg = (RadioGroup)mView.findViewById(R.id.radiogroup_search);
    	final RadioButton mCurrentPathButton = (RadioButton)mView.findViewById(R.id.radio_currentpath);
    	final RadioButton mWholePathButton = (RadioButton)mView.findViewById(R.id.radio_wholepath);
    	//设置默认选择在当前路径搜索
    	mCurrentPathButton.setChecked(true);
    	rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChanged(RadioGroup radiogroup, int checkId) {
				//当前路径的标志为1
				if(checkId == mCurrentPathButton.getId()){
					mRadioChecked = 1;
					//整个目录的标志为2
				}else if(checkId == mWholePathButton.getId()){
					mRadioChecked = 2;
				}
				
			}
		});
    	
    	//AlertDialog
    	Builder builder =new AlertDialog.Builder(MainActivity.this)
    						.setTitle("搜索").setView(mView)
    						.setPositiveButton("确定", new OnClickListener() {
								
								@Override
								public void onClick(DialogInterface arg0, int arg1) {
									// 获取搜索框的内容
									keyWords = ((EditText)mView.findViewById(R.id.edit_search)).getText().toString();
									if(keyWords.length() == 0){
										Toast.makeText(MainActivity.this, "关键字不能为空", Toast.LENGTH_SHORT).show();
									}else{
										if(position == 1){
											show.setText(mRootPath);
										}else{
											show.setText(mSDCard);
										}
										//获取用户输入的关键字并发送广播-开始
										Intent keywordIntent = new Intent();
										keywordIntent.setAction(KEYWORD_BROADCAST);
										//传递搜索的范围区间:1.当前路径下搜索 2.SD卡下搜索
										if(mRadioChecked == 1){
											keywordIntent.putExtra("searchpath", mCurrentFilePath);
										}else{
											keywordIntent.putExtra("searchpath", mSDCard);
										}
										//传递关键字
										keywordIntent.putExtra("keyword", keyWords);
										//到这里为止是携带关键字信息并发送了广播,会在Service服务当中接收该广播并提取关键字进行搜索
										getApplicationContext().sendBroadcast(keywordIntent);
										//开启服务,启动搜索
										serviceIntent = new Intent("com.android.service.FILE_SEARCH_START");
										MainActivity.this.startService(serviceIntent);
										isComeBackFromNotification = false;
									}
								}
							})
							.setPositiveButton("取消", null);
    	builder.create().show();
    }
    
    
    class FileBroadcast extends BroadcastReceiver{

		@Override
		public void onReceive(Context context, Intent intent) {
			mAction = intent.getAction();
			//搜索完毕
			if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){
				mFileName = intent.getStringArrayListExtra("mFileNameList");
				mFilePath = intent.getStringArrayListExtra("mFilePathsList");
				Toast.makeText(MainActivity.this, "搜索完毕!", Toast.LENGTH_SHORT).show();
				//这里搜索完毕之后应该弹出一个弹出框提示用户要不要显示数据
				searchCompletedDialog("搜索完毕,是否马上显示结果?");
			}
			//点击通知栏跳转过来的广播
			else if(FileService.FILE_NOTIFICATION.equals(mAction)){
				String mNotification = intent.getStringExtra("notification");
				Toast.makeText(MainActivity.this, mNotification, Toast.LENGTH_LONG).show();
			}
			searchCompletedDialog("你确定要取消搜索吗?");
		}
    	
    }
    
    //搜索完毕和点击通知过来时的提示框
    private void searchCompletedDialog(String message){
    	Builder searchDialog = new AlertDialog.Builder(MainActivity.this)
		.setTitle("提示")
		.setMessage(message)
		.setPositiveButton("确定", new OnClickListener(){
			public void onClick(DialogInterface dialog,int which) {
				//当弹出框时,需要对这个确定按钮进行一个判断,因为要对不同的情况做不同的处理(2种情况)
				// 1.搜索完毕
				// 2.取消搜索
				if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){
					if(mFileName.size() == 0){
			    		Toast.makeText(MainActivity.this, "无相关文件/文件夹!", Toast.LENGTH_SHORT).show();
			    		//清空列表
			    		list.setAdapter(new FileAdapter(MainActivity.this,mFileName,mFilePath));
			    	}else{ 
			    		//显示文件列表
			    		list.setAdapter(new FileAdapter(MainActivity.this,mFileName,mFilePath));
			    	}
				}else{
					//设置搜索标志为true,
					isComeBackFromNotification = true;
					//关闭服务,取消搜索
					getApplicationContext().stopService(serviceIntent);
				}
			}
		})
		.setNegativeButton("取消", null);
		searchDialog.create();
		searchDialog.show();
    }
    
    
    
    /**注册广播*/
    private IntentFilter mFilter;
    private FileBroadcast mFileBroadcast;
    private IntentFilter mIntentFilter;
	private SearcgBroadCast mServiceBroadCast;
	@Override
    protected void onStart() {
    	super.onStart();
    	mFilter = new IntentFilter();
    	mFilter.addAction(FileService.FILE_SEARCH_COMPLETED);
    	mFilter.addAction(FileService.FILE_NOTIFICATION);
    	mIntentFilter = new IntentFilter();
    	mIntentFilter.addAction(KEYWORD_BROADCAST);
    	if(mFileBroadcast == null){
    		mFileBroadcast = new FileBroadcast();
    	}
    	if(mServiceBroadCast == null){
    		mServiceBroadCast = new SearcgBroadCast();
    	}
    	//动态注册广播
    	this.registerReceiver(mFileBroadcast, mFilter);
    	this.registerReceiver(mServiceBroadCast, mIntentFilter);
    }
    
   
	/**注销广播*/
    @Override
	protected void onDestroy() {
		super.onDestroy();
		mFileName.clear();
		mFilePath.clear();
    	this.unregisterReceiver(mFileBroadcast);
    	this.unregisterReceiver(mServiceBroadCast);
	}
    
    /**创建文件夹的方法:当用户点击软件下面的创建菜单的时候,是在当前目录下创建的一个文件夹
     * 静态变量mCurrentFilePath存储的就是当前路径
     * java.io.File.separator是JAVA给我们提供的一个File类中的静态成员,它会根据系统的不同来创建分隔符
     * mNewFolderName正是我们要创建的新文件的名称,从EditText组件上得到的*/
    private void createFolder(){
    	//用于标识当前选中的是文件或者文件夹
    	mChecked = 2;
    	LayoutInflater mLI = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    	//初始化对话框布局
    	final LinearLayout mLL = (LinearLayout)mLI.inflate(R.layout.create_dialog, null);
    	RadioGroup mCreateRadioGroup = (RadioGroup)mLL.findViewById(R.id.radiogroup_create);
    	final RadioButton mCreateFileButton = (RadioButton)mLL.findViewById(R.id.create_file);
    	final RadioButton mCreateFolderButton = (RadioButton)mLL.findViewById(R.id.create_folder);
    	//设置默认为创建文件夹
    	mCreateFolderButton.setChecked(true);
    	//为按钮设置监听器
    	mCreateRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
    		//当选择改变时触发
			public void onCheckedChanged(RadioGroup arg0, int arg1) {
				if(arg1 == mCreateFileButton.getId()){
					mChecked = 1;
				}else if(arg1 == mCreateFolderButton.getId()){
					mChecked = 2;
				}
			}   		
    	});
    	//显示对话框
    	Builder mBuilder = new AlertDialog.Builder(MainActivity.this)
    	.setTitle("新建")
    	.setView(mLL)
    	.setPositiveButton("创建", new DialogInterface.OnClickListener(){
			public void onClick(DialogInterface dialog, int which) {
				//或者用户输入的名称
				mNewFolderName = ((EditText)mLL.findViewById(R.id.new_filename)).getText().toString();
				if(mChecked == 1){
					try {
						mCreateFile = new File(mCurrentFilePath+java.io.File.separator+mNewFolderName+".txt");
						mCreateFile.createNewFile();
						//刷新当前目录文件列表
						initFileListInfo(mCurrentFilePath);
					} catch (IOException e) {
						Toast.makeText(MainActivity.this, "文件名拼接出错..!!", Toast.LENGTH_SHORT).show();
					}
				}else if(mChecked == 2){
					mCreateFile = new File(mCurrentFilePath+java.io.File.separator+mNewFolderName);
					if(!mCreateFile.exists()&&!mCreateFile.isDirectory()&&mNewFolderName.length() != 0){
						if(mCreateFile.mkdirs()){
							//刷新当前目录文件列表
							initFileListInfo(mCurrentFilePath);
						}else{
							Toast.makeText(MainActivity.this, "创建失败,可能是系统权限不够,root一下?!", Toast.LENGTH_SHORT).show();
						}
					}else{
						Toast.makeText(MainActivity.this, "文件名为空,还是重名了呢?", Toast.LENGTH_SHORT).show();
					}
				}			
			}
    	}).setNeutralButton("取消", null);
    	mBuilder.show();
    }
    
    /**
     * @param 黏贴
     */
    private void palseFile(){
    	mNewFilePath = mCurrentFilePath+java.io.File.separator+mCopyFileName;//得到新路径
		if(!mOldFilePath.equals(mNewFilePath)&&isCopy == true){//在不同路径下复制才起效
			if(!new File(mNewFilePath).exists()){
				copyFile(mOldFilePath,mNewFilePath);
				Toast.makeText(MainActivity.this, "执行了粘贴", Toast.LENGTH_SHORT).show();
				initFileListInfo(mCurrentFilePath);
			}else{
				new AlertDialog.Builder(MainActivity.this)
				.setTitle("提示!")
				.setMessage("该文件名已存在,是否要覆盖?")
				.setPositiveButton("确定", new DialogInterface.OnClickListener(){
					public void onClick(DialogInterface dialog,int which){
						copyFile(mOldFilePath,mNewFilePath);
						initFileListInfo(mCurrentFilePath);
					}
				})
				.setNegativeButton("取消", null).show();
			}
		}else{
			Toast.makeText(MainActivity.this, "未复制文件!", Toast.LENGTH_LONG).show();
		}
    }
    
    private int i;
    FileInputStream fis;
	FileOutputStream fos;
    //复制文件
    private void copyFile(String oldFile,String newFile){
    	try {
			fis =  new FileInputStream(oldFile);
			fos = new FileOutputStream(newFile);
			do{
				//逐个byte读取文件,并写入另一个文件中
				if((i = fis.read()) != -1){
					fos.write(i);
				}
			}while(i != -1);
			//关闭输入文件流
			if(fis != null){
				fis.close();
			}
			//关闭输出文件流
			if(fos != null){
				fos.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    /**长按文件或文件夹时弹出的带ListView效果的功能菜单*/
	private void initItemLongClickListener(final File file){
		OnClickListener listener = new DialogInterface.OnClickListener(){
			//item的值就是从0开始的索引值(从列表的第一项开始)
			public void onClick(DialogInterface dialog, int item) {
				if(file.canRead()){//注意,所有对文件的操作必须是在该文件可读的情况下才可以,否则报错
					if(item == 0){//复制
						if(file.isFile()&&"txt".equals((file.getName().substring(file.getName().lastIndexOf(".")+1, file.getName().length())).toLowerCase())){
							Toast.makeText(MainActivity.this, "已复制!", Toast.LENGTH_SHORT).show();
							//复制标志位,表明已复制文件
							isCopy = true;
							//取得复制文件的名字
							mCopyFileName = file.getName();
							//记录复制文件的路径
							mOldFilePath = mCurrentFilePath+java.io.File.separator+mCopyFileName;
						}else{
							Toast.makeText(MainActivity.this, "对不起,目前只支持复制文本文件!", Toast.LENGTH_SHORT).show();
						}
					}
				}else{
					Toast.makeText(MainActivity.this, "对不起,您的访问权限不足!", Toast.LENGTH_SHORT).show();
				}
			}	
    	};
		//列表项名称
    	String[] mMenu = {"复制","重命名","删除"};
    	//显示操作选择对话框
    	new AlertDialog.Builder(MainActivity.this)
    								.setTitle("请选择操作!")
    								.setItems(mMenu, listener)
    								.setPositiveButton("取消",null).show();
    	
	}
	
	private void initListListener(){
		
		//这里还缺少单击打开文件和文件夹的功能。。。。
		
		//设置长按监听器
		list.setOnItemLongClickListener(new OnItemLongClickListener() {

			@Override
			public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
					int position, long arg3) {
				if(isAddBackUp == true){//说明存在返回根目录和返回上一级两列,接下来要对这两列进行屏蔽
					if(position != 0 && position != 1){
						initItemLongClickListener(new File(mFilePath.get(position)));
					}
				}
				if(mCurrentFilePath.equals(mRootPath)||mCurrentFilePath.equals(mSDCard)){
					initItemLongClickListener(new File(mFilePath.get(position)));
				}
				return false;
			}
		});
	}
	
}
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");
		}
		
	}

}










郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。