文件管理器

  1 package com.supermario.filemanager;
  2 
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileNotFoundException;
  6 import java.io.FileOutputStream;
  7 import java.io.IOException;
  8 import java.util.ArrayList;
  9 import java.util.HashMap;
 10 import java.util.List;
 11 
 12 
 13 
 14 import android.app.AlertDialog;
 15 import android.app.ListActivity;
 16 
 17 import android.app.AlertDialog.Builder;
 18 import android.content.BroadcastReceiver;
 19 import android.content.Context;
 20 import android.content.DialogInterface;
 21 import android.content.Intent;
 22 import android.content.IntentFilter;
 23 import android.content.ServiceConnection;
 24 import android.content.DialogInterface.OnClickListener;
 25 import android.graphics.Bitmap;
 26 import android.graphics.BitmapFactory;
 27 import android.net.Uri;
 28 import android.os.Bundle;
 29 import android.os.Environment;
 30 import android.util.Log;
 31 import android.view.Gravity;
 32 import android.view.LayoutInflater;
 33 import android.view.View;
 34 import android.view.ViewGroup;
 35 import android.widget.AdapterView;
 36 import android.widget.BaseAdapter;
 37 import android.widget.EditText;
 38 import android.widget.GridView;
 39 import android.widget.ImageView;
 40 import android.widget.LinearLayout;
 41 import android.widget.ListView;
 42 import android.widget.RadioButton;
 43 import android.widget.RadioGroup;
 44 import android.widget.SimpleAdapter;
 45 import android.widget.TextView;
 46 import android.widget.Toast;
 47 import android.widget.AdapterView.OnItemClickListener;
 48 import android.widget.AdapterView.OnItemLongClickListener;
 49 
 50 public class MainActivity extends ListActivity implements OnItemLongClickListener{
 51     // 声明成员变量:
 52     //存放显示的文件列表的名称
 53     private List<String> mFileNames = null;
 54     //存放显示的文件列表的相对应的路径
 55     private List<String> mFilePaths = null;
 56     //起始目录“/” 
 57     private String mRootPath = java.io.File.separator;
 58     // SD卡根目录
 59     private String mSDCard = Environment.getExternalStorageDirectory().toString();
 60     private String mOldFilePath = "";
 61     private String mNewFilePath = "";
 62     private String keyWords;
 63     //用于显示当前路径
 64     private TextView mPathTextView;
 65     //用于放置工具栏
 66     private GridView mToolbarGridView;
 67     private int[] girdview_menu_image = {R.drawable.menu_phone,R.drawable.menu_sdcard,R.drawable.menu_search,
 68                                                         R.drawable.menu_create,R.drawable.menu_palse,R.drawable.menu_exit};
 69     private String[] gridview_menu_title = {"手机","SD卡","搜索","创建","粘贴","退出"};
 70     // 代表手机或SD卡,1代表手机,2代表SD卡
 71     private static int menuPosition = 1;
 72     
 73     @Override
 74     public void onCreate(Bundle savedInstanceState) {
 75         super.onCreate(savedInstanceState);
 76         setContentView(R.layout.main);
 77         mPathTextView = (TextView)findViewById(R.id.mPath);
 78         mToolbarGridView = (GridView)findViewById(R.id.file_gridview_toolbar);
 79       //一开始程序的时候加载手机目录下的文件列表
 80         initFileListInfo(mRootPath);
 81         //初始化菜单视图
 82         initGridViewMenu();
 83         //初始化菜单监听器
 84         initMenuListener();
 85         //为列表项绑定长按监听器
 86         getListView().setOnItemLongClickListener(this);
 87        
 88         
 89          
 90     }
 91     
 92     public static String mCurrentFilePath="";
 93     private void initFileListInfo(String filePath) {
 94         mCurrentFilePath = filePath;
 95         //显示当前的路径
 96         mPathTextView.setText(filePath);
 97         mFileNames = new ArrayList<String>();
 98         mFilePaths = new ArrayList<String>();
 99         File mFile = new File(filePath);
100         //遍历出该文件夹路径下的所有文件/文件夹
101         File[] mFiles = mFile.listFiles();
102         //只要当前路径不是手机根目录或者是sd卡根目录则显示“返回根目录”和“返回上一级”
103         if(menuPosition == 1&&!mCurrentFilePath.equals(mRootPath)){
104             initAddBackUp(filePath,mRootPath);
105         }else if(menuPosition == 2&&!mCurrentFilePath.equals(mSDCard)){
106             initAddBackUp(filePath,mSDCard);
107         }
108         
109         /*将所有文件信息添加到集合中*/
110         for(File mCurrentFile:mFiles){
111             mFileNames.add(mCurrentFile.getName());
112             mFilePaths.add(mCurrentFile.getPath());
113         }
114         
115         /*适配数据*/
116         setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths));
117     }
118     
119     private boolean isAddBackUp = false;
120     private void initAddBackUp(String filePath,String phone_sdcard){
121         if(!filePath.equals(phone_sdcard)){
122             /*列表项的第一项设置为返回根目录*/
123             mFileNames.add("BacktoRoot");
124             mFilePaths.add(phone_sdcard);
125             
126             /*列表项的第二项设置为返回上一级*/
127             mFileNames.add("BacktoUp");
128             //回到当前目录的父目录即回到上级
129             mFilePaths.add(new File(filePath).getParent());
130             //将添加返回按键标识位置为true
131             isAddBackUp = true;
132         }
133         
134     }
135     
136     /**为GridView配饰菜单资源*/
137     private void initGridViewMenu(){
138          
139          //设置选中时候的背景图片
140          mToolbarGridView.setSelector(R.drawable.menu_item_selected);
141          //设置背景图片
142          mToolbarGridView.setBackgroundResource(R.drawable.menu_background);
143          //设置列数
144          mToolbarGridView.setNumColumns(6);
145          //设置剧中对齐
146          mToolbarGridView.setGravity(Gravity.CENTER);
147          //设置水平,垂直间距为10
148          mToolbarGridView.setVerticalSpacing(10);
149          mToolbarGridView.setHorizontalSpacing(10);
150          //设置适配器
151          mToolbarGridView.setAdapter(getMenuAdapter(gridview_menu_title,girdview_menu_image));
152     }
153     
154     /**菜单项的监听*/
155     protected void initMenuListener(){
156         mToolbarGridView.setOnItemClickListener(new OnItemClickListener(){
157 
158             public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
159                 switch(arg2)
160                 {
161                 //回到根目录
162                 case 0:
163                     menuPosition = 1;
164                      initFileListInfo(mRootPath);
165                     break;
166                 //回到SD卡根目录
167                 case 1:
168                     menuPosition = 2;
169                     initFileListInfo(mSDCard);
170                     break;
171                 //显示搜索对话框
172                 case 2:
173                     searchDilalog();
174                     break;
175 //                //创建文件夹
176                 case 3:
177                     createFolder();
178                     break;
179 //                //粘贴文件
180                 case 4:
181                     palseFile();
182                     break;
183                 //退出
184                 case 5:
185                     MainActivity.this.finish();
186                     break;
187                 }
188             }          
189         });
190     }
191     
192     
193     private String mNewFolderName = "";
194     private File mCreateFile;
195     private RadioGroup mCreateRadioGroup;
196     private static int mChecked;
197     /**创建文件夹的方法:当用户点击软件下面的创建菜单的时候,是在当前目录下创建的一个文件夹
198      * 静态变量mCurrentFilePath存储的就是当前路径
199      * java.io.File.separator是JAVA给我们提供的一个File类中的静态成员,它会根据系统的不同来创建分隔符
200      * mNewFolderName正是我们要创建的新文件的名称,从EditText组件上得到的*/
201     private void createFolder(){
202         //用于标识当前选中的是文件或者文件夹
203         mChecked = 2;
204         LayoutInflater mLI = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
205         //初始化对话框布局
206         final LinearLayout mLL = (LinearLayout)mLI.inflate(R.layout.create_dialog, null);
207         mCreateRadioGroup = (RadioGroup)mLL.findViewById(R.id.radiogroup_create);
208         final RadioButton mCreateFileButton = (RadioButton)mLL.findViewById(R.id.create_file);
209         final RadioButton mCreateFolderButton = (RadioButton)mLL.findViewById(R.id.create_folder);
210         //设置默认为创建文件夹
211         mCreateFolderButton.setChecked(true);
212         //为按钮设置监听器
213         mCreateRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
214             //当选择改变时触发
215             public void onCheckedChanged(RadioGroup arg0, int arg1) {
216                 if(arg1 == mCreateFileButton.getId()){
217                     mChecked = 1;
218                 }else if(arg1 == mCreateFolderButton.getId()){
219                     mChecked = 2;
220                 }
221             }           
222         });
223         //显示对话框
224         Builder mBuilder = new AlertDialog.Builder(MainActivity.this)
225         .setTitle("新建")
226         .setView(mLL)
227         .setPositiveButton("创建", new DialogInterface.OnClickListener(){
228             public void onClick(DialogInterface dialog, int which) {
229                 //或者用户输入的名称
230                 mNewFolderName = ((EditText)mLL.findViewById(R.id.new_filename)).getText().toString();
231                 if(mChecked == 1){
232                     try {
233                         mCreateFile = new File(mCurrentFilePath+java.io.File.separator+mNewFolderName+".txt");
234                         mCreateFile.createNewFile();
235                         //刷新当前目录文件列表
236                         initFileListInfo(mCurrentFilePath);
237                     } catch (IOException e) {
238                         Toast.makeText(MainActivity.this, "文件名拼接出错..!!", Toast.LENGTH_SHORT).show();
239                     }
240                 }else if(mChecked == 2){
241                     mCreateFile = new File(mCurrentFilePath+java.io.File.separator+mNewFolderName);
242                     if(!mCreateFile.exists()&&!mCreateFile.isDirectory()&&mNewFolderName.length() != 0){
243                         if(mCreateFile.mkdirs()){
244                             //刷新当前目录文件列表
245                             initFileListInfo(mCurrentFilePath);
246                         }else{
247                             Toast.makeText(MainActivity.this, "创建失败,可能是系统权限不够,root一下?!", Toast.LENGTH_SHORT).show();
248                         }
249                     }else{
250                         Toast.makeText(MainActivity.this, "文件名为空,还是重名了呢?", Toast.LENGTH_SHORT).show();
251                     }
252                 }            
253             }
254         }).setNeutralButton("取消", null);
255         mBuilder.show();
256     }
257     /**粘贴*/
258     private void palseFile(){
259         mNewFilePath = mCurrentFilePath+java.io.File.separator+mCopyFileName;//得到新路径
260         Log.d("copy", "mOldFilePath is "+mOldFilePath+"| mNewFilePath is "+mNewFilePath+"| isCopy is "+isCopy);
261         if(!mOldFilePath.equals(mNewFilePath)&&isCopy == true){//在不同路径下复制才起效
262             if(!new File(mNewFilePath).exists()){
263                 copyFile(mOldFilePath,mNewFilePath);
264                 Toast.makeText(MainActivity.this, "执行了粘贴", Toast.LENGTH_SHORT).show();
265                 initFileListInfo(mCurrentFilePath);
266             }else{
267                 new AlertDialog.Builder(MainActivity.this)
268                 .setTitle("提示!")
269                 .setMessage("该文件名已存在,是否要覆盖?")
270                 .setPositiveButton("确定", new DialogInterface.OnClickListener(){
271                     public void onClick(DialogInterface dialog,int which){
272                         copyFile(mOldFilePath,mNewFilePath);
273                         initFileListInfo(mCurrentFilePath);
274                     }
275                 })
276                 .setNegativeButton("取消", null).show();
277             }
278         }else{
279             Toast.makeText(MainActivity.this, "未复制文件!", Toast.LENGTH_LONG).show();
280         }
281     }
282     
283     private int i;
284     FileInputStream fis;
285     FileOutputStream fos;
286     //复制文件
287     private void copyFile(String oldFile,String newFile){
288         try {
289             fis =  new FileInputStream(oldFile);
290             fos = new FileOutputStream(newFile);
291             do{
292                 //逐个byte读取文件,并写入另一个文件中
293                 if((i = fis.read()) != -1){
294                     fos.write(i);
295                 }
296             }while(i != -1);
297             //关闭输入文件流
298             if(fis != null){
299                 fis.close();
300             }
301             //关闭输出文件流
302             if(fos != null){
303                 fos.close();
304             }
305         } catch (FileNotFoundException e) {
306             e.printStackTrace();
307         } catch (IOException e) {
308             e.printStackTrace();
309         }
310     }
311 
312     /**菜单适配器*/
313     private SimpleAdapter getMenuAdapter(String[] menuNameArray,
314             int[] imageResourceArray) {
315         //数组列表用于存放映射表
316         ArrayList<HashMap<String, Object>> mData = new ArrayList<HashMap<String, Object>>();
317         for (int i = 0; i < menuNameArray.length; i++) {
318             HashMap<String, Object> mMap = new HashMap<String, Object>();
319             //将“image”映射成图片资源
320             mMap.put("image", imageResourceArray[i]);
321             //将“title”映射成标题
322             mMap.put("title", menuNameArray[i]);        
323             mData.add(mMap);
324         }
325         //新建简单适配器,设置适配器的布局文件,映射关系
326         SimpleAdapter mAdapter = new SimpleAdapter(this, mData,R.layout.item_menu, new String[] { "image", "title" },new int[] { R.id.item_image, R.id.item_text });
327         return mAdapter;
328     }
329     /**列表项点击时的事件监听*/
330     @Override
331     protected void onListItemClick(ListView listView, View view, int position, long id){
332         final File mFile = new File(mFilePaths.get(position));
333         //如果该文件是可读的,我们进去查看文件
334         if(mFile.canRead()){
335             if(mFile.isDirectory()){
336                 //如果是文件夹,则直接进入该文件夹,查看文件目录
337                 initFileListInfo(mFilePaths.get(position));
338             }
339             else
340             {
341                 openFile(mFile);            
342             }
343             
344         }
345        else
346        {
347             //如果该文件不可读,我们给出提示不能访问,防止用户操作系统文件造成系统崩溃等
348             Toast.makeText(MainActivity.this, "对不起,您的访问权限不足!", Toast.LENGTH_SHORT).show();
349         }
350     }
351    
352     
353     /**调用系统的方法,来打开文件的方法*/
354     private void openFile(File file){
355         if(file.isDirectory()){
356             initFileListInfo(file.getPath());
357         }else{
358             Intent intent = new Intent();
359             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
360             intent.setAction(android.content.Intent.ACTION_VIEW);
361             //设置当前文件类型
362             intent.setDataAndType(Uri.fromFile(file), getMIMEType(file));
363             startActivity(intent);
364         }
365     }
366     /**获得MIME类型的方法*/
367     private String getMIMEType(File file){
368         String type = "";
369         String fileName = file.getName();
370         //取出文件后缀名并转成小写
371         String  fileEnds = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();
372         if(fileEnds.equals("m4a")||fileEnds.equals("mp3")||fileEnds.equals("mid")||fileEnds.equals("xmf")||fileEnds.equals("ogg")||fileEnds.equals("wav")){
373             type = "audio/*";// 系统将列出所有可能打开音频文件的程序选择器
374         }else if(fileEnds.equals("3gp")||fileEnds.equals("mp4")){
375             type = "video/*";// 系统将列出所有可能打开视频文件的程序选择器
376         }else if(fileEnds.equals("jpg")||fileEnds.equals("gif")||fileEnds.equals("png")||fileEnds.equals("jpeg")||fileEnds.equals("bmp")){
377             type = "image/*";// 系统将列出所有可能打开图片文件的程序选择器
378         }else{
379             type = "*/*"; // 系统将列出所有可能打开该文件的程序选择器
380         }
381         return type;
382     }
383     
384   
385   //长按列表项的事件监听:对长按需要进行一个控制,当列表中包括”返回根目录“和”返回上一级“时,需要对这两列进行屏蔽
386     
387     @Override
388     public boolean onItemLongClick(AdapterView<?> arg0, View arg1, final int position, long arg3) {
389         if(isAddBackUp == true){//说明存在返回根目录和返回上一级两列,接下来要对这两列进行屏蔽
390             if(position != 0 && position != 1){
391                 initItemLongClickListener(new File(mFilePaths.get(position)));
392             }
393         }
394         else{
395             initItemLongClickListener(new File(mFilePaths.get(position)));
396         }
397         return false;
398     }
399 
400     private String mCopyFileName;
401     private boolean isCopy = false;
402     /**长按文件或文件夹时弹出的带ListView效果的功能菜单*/
403     private void initItemLongClickListener(final File file){
404         OnClickListener listener = new DialogInterface.OnClickListener(){
405             //item的值就是从0开始的索引值(从列表的第一项开始)
406             public void onClick(DialogInterface dialog, int item) {
407                 if(file.canRead()){//注意,所有对文件的操作必须是在该文件可读的情况下才可以,否则报错
408                     if(item == 0){//复制
409                         if(file.isFile()&&"txt".equals((file.getName().substring(file.getName().lastIndexOf(".")+1, file.getName().length())).toLowerCase())){
410                             Toast.makeText(MainActivity.this, "已复制!", Toast.LENGTH_SHORT).show();
411                             //复制标志位,表明已复制文件
412                             isCopy = true;
413                             //取得复制文件的名字
414                             mCopyFileName = file.getName();
415                             //记录复制文件的路径
416                             mOldFilePath = mCurrentFilePath+java.io.File.separator+mCopyFileName;
417                         }else{
418                             Toast.makeText(MainActivity.this, "对不起,目前只支持复制文本文件!", Toast.LENGTH_SHORT).show();
419                         }
420                     }else if(item == 1){//重命名
421                         initRenameDialog(file);
422                     }else if(item == 2){//删除
423                         initDeleteDialog(file);
424                     }
425                 }else{
426                     Toast.makeText(MainActivity.this, "对不起,您的访问权限不足!", Toast.LENGTH_SHORT).show();
427                 }
428             }    
429         };
430         //列表项名称
431         String[] mMenu = {"复制","重命名","删除"};
432         //显示操作选择对话框
433         new AlertDialog.Builder(MainActivity.this)
434                                     .setTitle("请选择操作!")
435                                     .setItems(mMenu, listener)
436                                     .setPositiveButton("取消",null).show();
437     }
438     
439     
440     
441     EditText mET;
442     //显示重命名对话框
443     private void initRenameDialog(final File file){
444         LayoutInflater mLI = LayoutInflater.from(MainActivity.this);
445         //初始化重命名对话框
446         LinearLayout mLL = (LinearLayout)mLI.inflate(R.layout.rename_dialog, null);
447         mET = (EditText)mLL.findViewById(R.id.new_filename);
448         //显示当前的文件名
449         mET.setText(file.getName());
450         //设置监听器
451         OnClickListener listener = new DialogInterface.OnClickListener(){
452             public void onClick(DialogInterface dialog,int which){
453                 String modifyName = mET.getText().toString();
454                 final String modifyFilePath = file.getParentFile().getPath()+java.io.File.separator;
455                 final String newFilePath = modifyFilePath+modifyName;
456                 //判断该新的文件名是否已经在当前目录下存在
457                 if(new File(newFilePath).exists()){
458                     if(!modifyName.equals(file.getName())){//把“重命名”操作时没做任何修改的情况过滤掉
459                         //弹出该新命名后的文件已经存在的提示,并提示接下来的操作
460                         new AlertDialog.Builder(MainActivity.this)
461                         .setTitle("提示!")
462                         .setMessage("该文件名已存在,是否要覆盖?")
463                         .setPositiveButton("确定", new DialogInterface.OnClickListener(){
464                             public void onClick(DialogInterface dialog,int which){
465                                 file.renameTo(new File(newFilePath));
466                                 Toast.makeText(MainActivity.this,
467                             "the file path is "+new File(newFilePath), Toast.LENGTH_SHORT).show();
468                                 //更新当前目录信息
469                                 initFileListInfo(file.getParentFile().getPath());
470                             }
471                         })
472                         .setNegativeButton("取消", null).show();
473                     }
474                 }else{
475                     //文件名不重复时直接修改文件名后再次刷新列表
476                     file.renameTo(new File(newFilePath));
477                     initFileListInfo(file.getParentFile().getPath());
478                 }
479             }
480             
481         };
482         //显示对话框
483         AlertDialog renameDialog = new AlertDialog.Builder(MainActivity.this).create();
484         renameDialog.setView(mLL);
485         renameDialog.setButton("确定", listener);
486         renameDialog.setButton2("取消", new DialogInterface.OnClickListener(){        
487             public void onClick(DialogInterface dialog,int which){
488             //什么都不做,关闭当前对话框
489             }        
490         });
491         renameDialog.show();
492     }
493     
494   //弹出删除文件/文件夹的对话框
495     private void initDeleteDialog(final File file){
496         new AlertDialog.Builder(MainActivity.this)
497                                     .setTitle("提示!")
498                                     .setMessage("您确定要删除该"+(file.isDirectory()?"文件夹":"文件")+"吗?")
499                                     .setPositiveButton("确定", new DialogInterface.OnClickListener(){
500                                         public void onClick(DialogInterface dialog,int which){
501                                             if(file.isFile()){
502                                                 //是文件则直接删除
503                                                 file.delete();
504                                             }else{
505                                                 //是文件夹则用这个方法删除
506                                                 deleteFolder(file);
507                                             }
508                                             //重新遍历该文件的父目录
509                                             initFileListInfo(file.getParent());
510                                         }
511                                     })
512                                     .setNegativeButton("取消", null).show();
513     }
514     
515     //删除文件夹的方法(递归删除该文件夹下的所有文件)
516     public void deleteFolder(File folder){
517         File[] fileArray = folder.listFiles();
518         if(fileArray.length == 0){
519             //空文件夹则直接删除
520             folder.delete();
521         }else{
522             //遍历该目录
523             for(File currentFile:fileArray){
524                 if(currentFile.exists()&&currentFile.isFile()){
525                     //文件则直接删除
526                     currentFile.delete();
527                 }else{
528                     //递归删除
529                     deleteFolder(currentFile);
530                 }
531             }
532             folder.delete();
533         }
534     } 
535     
536     Intent serviceIntent;
537     ServiceConnection mSC;
538     RadioGroup mRadioGroup;
539     static int mRadioChecked;
540     public static final String KEYWORD_BROADCAST = "com.supermario.file.KEYWORD_BROADCAST";
541     //显示搜索对话框
542     private void searchDilalog(){
543         //用于确定是在当前目录搜索或者是在整个目录搜索的标志
544         mRadioChecked = 1;
545         LayoutInflater mLI = LayoutInflater.from(MainActivity.this);
546         final View mLL = (View)mLI.inflate(R.layout.search_dialog, null);
547         mRadioGroup = (RadioGroup)mLL.findViewById(R.id.radiogroup_search);
548         final RadioButton mCurrentPathButton = (RadioButton)mLL.findViewById(R.id.radio_currentpath);
549         final RadioButton mWholePathButton = (RadioButton)mLL.findViewById(R.id.radio_wholepath);
550         //设置默认选择在当前路径搜
551         mCurrentPathButton.setChecked(true);
552         mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
553             //当选择改变时触发
554             public void onCheckedChanged(RadioGroup radiogroup, int checkId) {
555                 //当前路径的标志为1
556                 if(checkId == mCurrentPathButton.getId()){
557                     mRadioChecked = 1;
558                     //整个目录的标志为2
559                 }else if(checkId == mWholePathButton.getId()){
560                     mRadioChecked = 2;
561                 }
562             }    
563         });
564         Builder mBuilder = new AlertDialog.Builder(MainActivity.this)
565                                     .setTitle("搜索").setView(mLL)
566                                     .setPositiveButton("确定", new OnClickListener(){
567                                         public void onClick(DialogInterface arg0, int arg1) {
568                                             keyWords = ((EditText)mLL.findViewById(R.id.edit_search)).getText().toString();
569                                             if(keyWords.length() == 0){
570                                                 Toast.makeText(MainActivity.this, "关键字不能为空!", Toast.LENGTH_SHORT).show();
571                                                 searchDilalog();
572                                             }else{
573                                                 if(menuPosition == 1){
574                                                     mPathTextView.setText(mRootPath);
575                                                 }else{
576                                                     mPathTextView.setText(mSDCard);
577                                                 }
578                                                 //获取用户输入的关键字并开始搜索服务
579                                                 serviceIntent = new Intent("com.android.service.FILE_SEARCH_START");
580                                                 //传递搜索的范围区间:1.当前路径下搜索 2.SD卡下搜索
581                                                 if(mRadioChecked == 1){
582                                                     serviceIntent.putExtra("searchpath", mCurrentFilePath);
583                                                 }else{
584                                                     serviceIntent.putExtra("searchpath", mSDCard);
585                                                 }
586                                                 //传递关键字
587                                                 serviceIntent.putExtra("keyword", keyWords);
588                                                 
589                                                 
590                                                 MainActivity.this.startService(serviceIntent);//开启服务,启动搜索
591                                                 isComeBackFromNotification = false;
592                                             }
593                                         }
594                                     })
595                                     .setNegativeButton("取消", null);
596         mBuilder.create().show();
597     }
598     
599     /**注册广播*/
600     private IntentFilter mFilter;
601     private FileBroadcast mFileBroadcast;
602     private IntentFilter mIntentFilter;
603     @Override
604     protected void onStart() {
605         super.onStart();
606         mFilter = new IntentFilter();
607         mFilter.addAction(FileService.FILE_SEARCH_COMPLETED);
608         mFilter.addAction(FileService.FILE_NOTIFICATION);
609         if(mFileBroadcast == null){
610             mFileBroadcast = new FileBroadcast();
611         }
612         
613         this.registerReceiver(mFileBroadcast, mFilter);
614         
615     }
616     
617    
618     /**注销广播*/
619     @Override
620     protected void onDestroy() {
621         super.onDestroy();
622         Log.d("NullPointError", "onDestroy");
623         mFileNames.clear();
624         mFilePaths.clear();
625         this.unregisterReceiver(mFileBroadcast);
626     }
627     
628     private String mAction;
629     public static boolean isComeBackFromNotification = false;
630     /**内部广播类*/
631     class FileBroadcast extends BroadcastReceiver{
632         @Override
633         public void onReceive(Context context, Intent intent) {
634             mAction = intent.getAction();
635             // 搜索完毕的广播
636             if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){
637                 mFileNames = intent.getStringArrayListExtra("mFileNameList");
638                 mFilePaths = intent.getStringArrayListExtra("mFilePathsList");
639                 Toast.makeText(MainActivity.this, "搜索完毕!", Toast.LENGTH_SHORT).show();
640                 //这里搜索完毕之后应该弹出一个弹出框提示用户要不要显示数据
641                 searchCompletedDialog("搜索完毕,是否马上显示结果?");
642                 getApplicationContext().stopService(serviceIntent);//当搜索完毕的时候停止服务,然后在服务中取消通知
643             // 点击通知栏跳转过来的广播
644             }else if(FileService.FILE_NOTIFICATION.equals(mAction)){//点击通知回到当前Activity,读取其中信息
645                 String mNotification = intent.getStringExtra("notification");
646                 Toast.makeText(MainActivity.this, mNotification, Toast.LENGTH_LONG).show();
647                 searchCompletedDialog("你确定要取消搜索吗?");
648             }
649         }
650     }
651     
652     //搜索完毕和点击通知过来时的提示框
653     private void searchCompletedDialog(String message){
654         Builder searchDialog = new AlertDialog.Builder(MainActivity.this)
655         .setTitle("提示")
656         .setMessage(message)
657         .setPositiveButton("确定", new OnClickListener(){
658             public void onClick(DialogInterface dialog,int which) {
659                 //当弹出框时,需要对这个确定按钮进行一个判断,因为要对不同的情况做不同的处理(2种情况)
660                 // 1.搜索完毕
661                 // 2.取消搜索
662                 if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){
663                     if(mFileNames.size() == 0){
664                         Toast.makeText(MainActivity.this, "无相关文件/文件夹!", Toast.LENGTH_SHORT).show();
665                         setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths));//清空列表
666                     }else{ 
667                         //显示文件列表
668                         setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths));
669                     }
670                 }else{
671                     //设置搜索标志为true,
672                     isComeBackFromNotification = true;
673                     //关闭服务,取消搜索
674                     getApplicationContext().stopService(serviceIntent);
675                 }
676             }
677         })
678         .setNegativeButton("取消", null);
679         searchDialog.create();
680         searchDialog.show();
681     }
682     
683 
684     class FileAdapter extends BaseAdapter{
685         //返回键,各种格式的文件的图标
686         private Bitmap mBackRoot;
687         private Bitmap mBackUp;
688         private Bitmap mImage;
689         private Bitmap mAudio;
690         private Bitmap mRar;
691         private Bitmap mVideo;
692         private Bitmap mFolder;
693         private Bitmap mApk;
694         private Bitmap mOthers;
695         private Bitmap mTxt;
696         private Bitmap mWeb;     
697         private Context mContext;
698         //文件名列表
699         private List<String> mFileNameList;
700         //文件对应的路径列表
701         private List<String> mFilePathList;
702       
703         public FileAdapter(Context context,List<String> fileName,List<String> filePath){
704             mContext = context;
705             mFileNameList = fileName;
706             mFilePathList = filePath;
707             //初始化图片资源
708             //返回到根目录
709             mBackRoot = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_root);
710             //返回到上一级目录
711             mBackUp = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_up);
712             //图片文件对应的icon
713             mImage = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.image);
714             //音频文件对应的icon
715             mAudio = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.audio);
716             //视频文件对应的icon
717             mVideo = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.video);
718             //可执行文件对应的icon
719             mApk = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.apk);
720             //文本文档对应的icon
721             mTxt = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.txt);
722             //其他类型文件对应的icon
723             mOthers = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.others);
724             //文件夹对应的icon
725             mFolder = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.folder);
726             //zip文件对应的icon
727             mRar = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.zip_icon);
728             //网页文件对应的icon
729             mWeb = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.web_browser);
730         }
731         //获得文件的总数    
732         @Override
733         public int getCount() {
734             return mFilePathList.size();
735         }
736         //获得当前位置对应的文件名
737         @Override
738         public Object getItem(int position) {
739             return mFileNameList.get(position);
740         }
741         //获得当前的位置
742         @Override
743         public long getItemId(int position) {
744             return position;
745         }
746         //获得视图
747         @Override
748         public View getView(int position, View convertView, ViewGroup viewgroup) {
749             ViewHolder viewHolder = null;
750             if (convertView == null) {
751                 viewHolder = new ViewHolder();
752                 LayoutInflater mLI = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
753                 //初始化列表元素界面
754                 convertView = mLI.inflate(R.layout.list_child, null);
755                 //获取列表布局界面元素
756                 viewHolder.mIV = (ImageView)convertView.findViewById(R.id.image_list_childs);
757                 viewHolder.mTV = (TextView)convertView.findViewById(R.id.text_list_childs);
758                 //将每一行的元素集合设置成标签
759                 convertView.setTag(viewHolder);
760             } else {
761                 //获取视图标签
762                 viewHolder = (ViewHolder) convertView.getTag();
763             }
764             File mFile = new File(mFilePathList.get(position).toString());
765             //如果                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
766             if(mFileNameList.get(position).toString().equals("BacktoRoot")){
767                 //添加返回根目录的按钮
768                 viewHolder.mIV.setImageBitmap(mBackRoot);
769                 viewHolder.mTV.setText("返回根目录");
770             }else if(mFileNameList.get(position).toString().equals("BacktoUp")){
771                 //添加返回上一级菜单的按钮
772                 viewHolder.mIV.setImageBitmap(mBackUp);
773                 viewHolder.mTV.setText("返回上一级");
774             }else if(mFileNameList.get(position).toString().equals("BacktoSearchBefore")){
775                 //添加返回搜索之前目录的按钮
776                 viewHolder.mIV.setImageBitmap(mBackRoot);
777                 viewHolder.mTV.setText("返回搜索之前目录");
778             }else{
779                 String fileName = mFile.getName();
780                 viewHolder.mTV.setText(fileName);
781                 if(mFile.isDirectory()){
782                     viewHolder.mIV.setImageBitmap(mFolder);
783                 }else{
784                     String fileEnds = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();//取出文件后缀名并转成小写
785                     if(fileEnds.equals("m4a")||fileEnds.equals("mp3")||fileEnds.equals("mid")||fileEnds.equals("xmf")||fileEnds.equals("ogg")||fileEnds.equals("wav")){
786                         viewHolder.mIV.setImageBitmap(mVideo);
787                     }else if(fileEnds.equals("3gp")||fileEnds.equals("mp4")){
788                         viewHolder.mIV.setImageBitmap(mAudio);
789                     }else if(fileEnds.equals("jpg")||fileEnds.equals("gif")||fileEnds.equals("png")||fileEnds.equals("jpeg")||fileEnds.equals("bmp")){
790                         viewHolder.mIV.setImageBitmap(mImage);
791                     }else if(fileEnds.equals("apk")){
792                         viewHolder.mIV.setImageBitmap(mApk);
793                     }else if(fileEnds.equals("txt")){
794                         viewHolder.mIV.setImageBitmap(mTxt);
795                     }else if(fileEnds.equals("zip")||fileEnds.equals("rar")){
796                         viewHolder.mIV.setImageBitmap(mRar);
797                     }else if(fileEnds.equals("html")||fileEnds.equals("htm")||fileEnds.equals("mht")){
798                         viewHolder.mIV.setImageBitmap(mWeb);
799                     }else {
800                         viewHolder.mIV.setImageBitmap(mOthers);
801                     }
802                 }                
803             }
804             return convertView;
805         }
806         //用于存储列表每一行元素的图片和文本
807         class ViewHolder {
808             ImageView mIV;
809             TextView mTV;
810         }
811         
812         
813     }
814 
815 
816 }
817 
818     
819     

MainActivity.java

  1 package com.supermario.filemanager;
  2 import java.io.File;
  3 import java.util.ArrayList;
  4 import android.app.Notification;
  5 import android.app.NotificationManager;
  6 import android.app.PendingIntent;
  7 import android.app.Service;
  8 import android.content.Intent;
  9 import android.os.AsyncTask;
 10 import android.os.IBinder;
 11 import android.util.Log;
 12 public class FileService extends Service {    
 13 
 14     private ArrayList<String> mFileName = null;
 15     private ArrayList<String> mFilePaths = null;
 16     public static  String mServiceKeyword = "";//接收搜索关键字的静态变量
 17     public static  String mServiceSearchPath = "";//接收搜索路径的静态变量   
 18     public static final String FILE_SEARCH_COMPLETED = "com.supermario.file.FILE_SEARCH_COMPLETED";
 19     public static final String FILE_NOTIFICATION = "com.supermario.file.FILE_NOTIFICATION";    
 20     @Override
 21     public IBinder onBind(Intent arg0) {
 22         return null;
 23     }    
 24     
 25 
 26     @Override
 27     public int onStartCommand(Intent intent, int flags, int startId) {
 28         mServiceKeyword=intent.getStringExtra("keyword");
 29         mServiceSearchPath=intent.getStringExtra("searchpath");
 30         mFileName = new ArrayList<String>();
 31         mFilePaths = new ArrayList<String>();
 32         //发出通知表明正在进行搜索
 33         fileSearchNotification();
 34         new DoBackgroundTask().execute();
 35         return START_STICKY;
 36     }
 37     
 38     private int m = -1;
 39     /**具体做搜索事件的可回调函数*/
 40     private void initFileArray(File file){
 41         Log.d("FileService", "currentArray is "+file.getPath());
 42         //只能遍历可读的文件夹,否则会报错
 43         if(file.canRead()){
 44             File[] mFileArray = file.listFiles();
 45             for(File currentArray:mFileArray){
 46                 if(currentArray.getName().indexOf(mServiceKeyword) != -1){
 47                     if (m == -1) {
 48                         m++;
 49                         // 返回搜索之前目录
 50                         mFileName.add("BacktoSearchBefore");
 51                         mFilePaths.add(MainActivity.mCurrentFilePath);
 52                     }
 53                     mFileName.add(currentArray.getName());
 54                     mFilePaths.add(currentArray.getPath());
 55                 }
 56                 //如果是文件夹则回调该方法
 57                 if(currentArray.exists()&&currentArray.isDirectory()){
 58                     //如果用户取消了搜索,应该停止搜索的过程
 59                     if(MainActivity.isComeBackFromNotification == true){
 60                         return;
 61                     }
 62                     initFileArray(currentArray);
 63                 }
 64             }
 65         }                                                                                                                                                                                                                                                                                                                                                                                            
 66     }    
 67      
 68     private class DoBackgroundTask extends AsyncTask<java.lang.Void, java.lang.Void, java.lang.Void>
 69     {
 70         
 71         
 72          @Override
 73          protected Void doInBackground(Void... params) {
 74              // TODO Auto-generated method stub
 75              
 76                initFileArray(new File(mServiceSearchPath));
 77                 //当用户点击了取消搜索则不发生广播
 78                 Intent intent = new Intent(FILE_SEARCH_COMPLETED);
 79                 if(MainActivity.isComeBackFromNotification == false){
 80                      
 81                      intent.putStringArrayListExtra("mFileNameList", mFileName);
 82                      intent.putStringArrayListExtra("mFilePathsList", mFilePaths);
 83                       sendBroadcast(intent);
 84                  }
 85               
 86              return null;
 87          }
 88   
 89          protected void onPostExecute(Long result) {
 90             //搜索完毕之后携带数据并发送广播
 91              
 92          }
 93 
 94     }
 95     
 96 
 97     @Override
 98     public void onDestroy() {
 99         super.onDestroy();
100         //取消通知
101         mNF.cancel(R.string.app_name);
102     }    
103     
104     
105     NotificationManager mNF;
106     /**通知*/
107     private void fileSearchNotification(){
108         Notification mNotification = new Notification(R.drawable.logo,"后台搜索中...",System.currentTimeMillis());
109         Intent intent = new Intent(FILE_NOTIFICATION);
110         //打开notice时的提示内容
111         intent.putExtra("notification", "当通知还存在,说明搜索未完成,可以在这里触发一个事件,当点击通知回到Activity之后,可以弹出一个框,提示是否取消搜索!");
112         PendingIntent mPI = PendingIntent.getBroadcast(this,0,intent,0);
113         mNotification.setLatestEventInfo(this, "在"+mServiceSearchPath+"下搜索", "搜索关键字为"+mServiceKeyword+"【点击可取消搜索】", mPI);
114         if(mNF == null){
115             mNF = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
116         }
117         mNF.notify(R.string.app_name, mNotification);
118     }  
119 }


 

FileService.JAVA  搜索服务

源文件下载

原文地址:https://www.cnblogs.com/hixin/p/4098299.html