首页 > 代码库 > 文件管理器

文件管理器

  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 import com.supermario.filemanager.MainActivity.FileAdapter.ViewHolder; 13  14 import android.app.AlertDialog; 15 import android.app.ListActivity; 16 import android.app.ProgressDialog; 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             //将添加返回按键标识位置为true131             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          //设置水平,垂直间距为10148          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 = http://www.mamicode.com/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     @Override331     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             else340             {341                 openFile(mFile);            342             }343             344         }345        else346        {347             //如果该文件不可读,我们给出提示不能访问,防止用户操作系统文件造成系统崩溃等348             Toast.makeText(MainActivity.this, "对不起,您的访问权限不足!", Toast.LENGTH_SHORT).show();349         }350     }351     352     /**调用系统的方法,来打开文件的方法*/353     private void openFile(File file){354         if(file.isDirectory()){355             initFileListInfo(file.getPath());356         }else{357             Intent intent = new Intent();358             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);359             intent.setAction(android.content.Intent.ACTION_VIEW);360             //设置当前文件类型361             intent.setDataAndType(Uri.fromFile(file), getMIMEType(file));362             startActivity(intent);363         }364     }365     /**获得MIME类型的方法*/366     private String getMIMEType(File file){367         String type = "";368         String fileName = file.getName();369         //取出文件后缀名并转成小写370         String  fileEnds = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();371         if(fileEnds.equals("m4a")||fileEnds.equals("mp3")||fileEnds.equals("mid")||fileEnds.equals("xmf")||fileEnds.equals("ogg")||fileEnds.equals("wav")){372             type = "audio/*";// 系统将列出所有可能打开音频文件的程序选择器373         }else if(fileEnds.equals("3gp")||fileEnds.equals("mp4")){374             type = "video/*";// 系统将列出所有可能打开视频文件的程序选择器375         }else if(fileEnds.equals("jpg")||fileEnds.equals("gif")||fileEnds.equals("png")||fileEnds.equals("jpeg")||fileEnds.equals("bmp")){376             type = "image/*";// 系统将列出所有可能打开图片文件的程序选择器377         }else{378             type = "*/*"; // 系统将列出所有可能打开该文件的程序选择器379         }380         return type;381     }382     383   384   //长按列表项的事件监听:对长按需要进行一个控制,当列表中包括”返回根目录“和”返回上一级“时,需要对这两列进行屏蔽385     386     @Override387     public boolean onItemLongClick(AdapterView<?> arg0, View arg1, final int position, long arg3) {388         if(isAddBackUp == true){//说明存在返回根目录和返回上一级两列,接下来要对这两列进行屏蔽389             if(position != 0 && position != 1){390                 initItemLongClickListener(new File(mFilePaths.get(position)));391             }392         }393         else{394             initItemLongClickListener(new File(mFilePaths.get(position)));395         }396         return false;397     }398 399     private String mCopyFileName;400     private boolean isCopy = false;401     /**长按文件或文件夹时弹出的带ListView效果的功能菜单*/402     private void initItemLongClickListener(final File file){403         OnClickListener listener = new DialogInterface.OnClickListener(){404             //item的值就是从0开始的索引值(从列表的第一项开始)405             public void onClick(DialogInterface dialog, int item) {406                 if(file.canRead()){//注意,所有对文件的操作必须是在该文件可读的情况下才可以,否则报错407                     if(item == 0){//复制408                         if(file.isFile()&&"txt".equals((file.getName().substring(file.getName().lastIndexOf(".")+1, file.getName().length())).toLowerCase())){409                             Toast.makeText(MainActivity.this, "已复制!", Toast.LENGTH_SHORT).show();410                             //复制标志位,表明已复制文件411                             isCopy = true;412                             //取得复制文件的名字413                             mCopyFileName = file.getName();414                             //记录复制文件的路径415                             mOldFilePath = mCurrentFilePath+java.io.File.separator+mCopyFileName;416                         }else{417                             Toast.makeText(MainActivity.this, "对不起,目前只支持复制文本文件!", Toast.LENGTH_SHORT).show();418                         }419                     }else if(item == 1){//重命名420                         initRenameDialog(file);421                     }else if(item == 2){//删除422                         initDeleteDialog(file);423                     }424                 }else{425                     Toast.makeText(MainActivity.this, "对不起,您的访问权限不足!", Toast.LENGTH_SHORT).show();426                 }427             }    428         };429         //列表项名称430         String[] mMenu = {"复制","重命名","删除"};431         //显示操作选择对话框432         new AlertDialog.Builder(MainActivity.this)433                                     .setTitle("请选择操作!")434                                     .setItems(mMenu, listener)435                                     .setPositiveButton("取消",null).show();436     }437     438     439     440     EditText mET;441     //显示重命名对话框442     private void initRenameDialog(final File file){443         LayoutInflater mLI = LayoutInflater.from(MainActivity.this);444         //初始化重命名对话框445         LinearLayout mLL = (LinearLayout)mLI.inflate(R.layout.rename_dialog, null);446         mET = (EditText)mLL.findViewById(R.id.new_filename);447         //显示当前的文件名448         mET.setText(file.getName());449         //设置监听器450         OnClickListener listener = new DialogInterface.OnClickListener(){451             public void onClick(DialogInterface dialog,int which){452                 String modifyName = mET.getText().toString();453                 final String modifyFilePath = file.getParentFile().getPath()+java.io.File.separator;454                 final String newFilePath = modifyFilePath+modifyName;455                 //判断该新的文件名是否已经在当前目录下存在456                 if(new File(newFilePath).exists()){457                     if(!modifyName.equals(file.getName())){//把“重命名”操作时没做任何修改的情况过滤掉458                         //弹出该新命名后的文件已经存在的提示,并提示接下来的操作459                         new AlertDialog.Builder(MainActivity.this)460                         .setTitle("提示!")461                         .setMessage("该文件名已存在,是否要覆盖?")462                         .setPositiveButton("确定", new DialogInterface.OnClickListener(){463                             public void onClick(DialogInterface dialog,int which){464                                 file.renameTo(new File(newFilePath));465                                 Toast.makeText(MainActivity.this,466                             "the file path is "+new File(newFilePath), Toast.LENGTH_SHORT).show();467                                 //更新当前目录信息468                                 initFileListInfo(file.getParentFile().getPath());469                             }470                         })471                         .setNegativeButton("取消", null).show();472                     }473                 }else{474                     //文件名不重复时直接修改文件名后再次刷新列表475                     file.renameTo(new File(newFilePath));476                     initFileListInfo(file.getParentFile().getPath());477                 }478             }479             480         };481         //显示对话框482         AlertDialog renameDialog = new AlertDialog.Builder(MainActivity.this).create();483         renameDialog.setView(mLL);484         renameDialog.setButton("确定", listener);485         renameDialog.setButton2("取消", new DialogInterface.OnClickListener(){        486             public void onClick(DialogInterface dialog,int which){487             //什么都不做,关闭当前对话框488             }        489         });490         renameDialog.show();491     }492     493   //弹出删除文件/文件夹的对话框494     private void initDeleteDialog(final File file){495         new AlertDialog.Builder(MainActivity.this)496                                     .setTitle("提示!")497                                     .setMessage("您确定要删除该"+(file.isDirectory()?"文件夹":"文件")+"吗?")498                                     .setPositiveButton("确定", new DialogInterface.OnClickListener(){499                                         public void onClick(DialogInterface dialog,int which){500                                             if(file.isFile()){501                                                 //是文件则直接删除502                                                 file.delete();503                                             }else{504                                                 //是文件夹则用这个方法删除505                                                 deleteFolder(file);506                                             }507                                             //重新遍历该文件的父目录508                                             initFileListInfo(file.getParent());509                                         }510                                     })511                                     .setNegativeButton("取消", null).show();512     }513     514     //删除文件夹的方法(递归删除该文件夹下的所有文件)515     public void deleteFolder(File folder){516         File[] fileArray = folder.listFiles();517         if(fileArray.length == 0){518             //空文件夹则直接删除519             folder.delete();520         }else{521             //遍历该目录522             for(File currentFile:fileArray){523                 if(currentFile.exists()&&currentFile.isFile()){524                     //文件则直接删除525                     currentFile.delete();526                 }else{527                     //递归删除528                     deleteFolder(currentFile);529                 }530             }531             folder.delete();532         }533     } 534     535     Intent serviceIntent;536     ServiceConnection mSC;537     RadioGroup mRadioGroup;538     static int mRadioChecked;539     public static final String KEYWORD_BROADCAST = "com.supermario.file.KEYWORD_BROADCAST";540     //显示搜索对话框541     private void searchDilalog(){542         //用于确定是在当前目录搜索或者是在整个目录搜索的标志543         mRadioChecked = 1;544         LayoutInflater mLI = LayoutInflater.from(MainActivity.this);545         final View mLL = (View)mLI.inflate(R.layout.search_dialog, null);546         mRadioGroup = (RadioGroup)mLL.findViewById(R.id.radiogroup_search);547         final RadioButton mCurrentPathButton = (RadioButton)mLL.findViewById(R.id.radio_currentpath);548         final RadioButton mWholePathButton = (RadioButton)mLL.findViewById(R.id.radio_wholepath);549         //设置默认选择在当前路径搜550         mCurrentPathButton.setChecked(true);551         mRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){552             //当选择改变时触发553             public void onCheckedChanged(RadioGroup radiogroup, int checkId) {554                 //当前路径的标志为1555                 if(checkId == mCurrentPathButton.getId()){556                     mRadioChecked = 1;557                     //整个目录的标志为2558                 }else if(checkId == mWholePathButton.getId()){559                     mRadioChecked = 2;560                 }561             }    562         });563         Builder mBuilder = new AlertDialog.Builder(MainActivity.this)564                                     .setTitle("搜索").setView(mLL)565                                     .setPositiveButton("确定", new OnClickListener(){566                                         public void onClick(DialogInterface arg0, int arg1) {567                                             keyWords = ((EditText)mLL.findViewById(R.id.edit_search)).getText().toString();568                                             if(keyWords.length() == 0){569                                                 Toast.makeText(MainActivity.this, "关键字不能为空!", Toast.LENGTH_SHORT).show();570                                                 searchDilalog();571                                             }else{572                                                 if(menuPosition == 1){573                                                     mPathTextView.setText(mRootPath);574                                                 }else{575                                                     mPathTextView.setText(mSDCard);576                                                 }577                                                 //获取用户输入的关键字并发送广播-开始578                                                 Intent keywordIntent = new Intent();579                                                 keywordIntent.setAction(KEYWORD_BROADCAST);580                                                 //传递搜索的范围区间:1.当前路径下搜索 2.SD卡下搜索581                                                 if(mRadioChecked == 1){582                                                     keywordIntent.putExtra("searchpath", mCurrentFilePath);583                                                 }else{584                                                     keywordIntent.putExtra("searchpath", mSDCard);585                                                 }586                                                 //传递关键字587                                                 keywordIntent.putExtra("keyword", keyWords);588                                                 //到这里为止是携带关键字信息并发送了广播,会在Service服务当中接收该广播并提取关键字进行搜索589                                                 getApplicationContext().sendBroadcast(keywordIntent);590                                                 serviceIntent = new Intent("com.android.service.FILE_SEARCH_START");591                                                 MainActivity.this.startService(serviceIntent);//开启服务,启动搜索592                                                 isComeBackFromNotification = false;593                                             }594                                         }595                                     })596                                     .setNegativeButton("取消", null);597         mBuilder.create().show();598     }599     600     /**注册广播*/601     private IntentFilter mFilter;602     private FileBroadcast mFileBroadcast;603     private IntentFilter mIntentFilter;604     private SearchBroadCast mServiceBroadCast;605     @Override606     protected void onStart() {607         super.onStart();608         mFilter = new IntentFilter();609         mFilter.addAction(FileService.FILE_SEARCH_COMPLETED);610         mFilter.addAction(FileService.FILE_NOTIFICATION);611         mIntentFilter = new IntentFilter();612         mIntentFilter.addAction(KEYWORD_BROADCAST);613         if(mFileBroadcast == null){614             mFileBroadcast = new FileBroadcast();615         }616         if(mServiceBroadCast == null){617             mServiceBroadCast = new SearchBroadCast();618         }619         this.registerReceiver(mFileBroadcast, mFilter);620         this.registerReceiver(mServiceBroadCast, mIntentFilter);621     }622     623    624     /**注销广播*/625     @Override626     protected void onDestroy() {627         super.onDestroy();628         Log.d("NullPointError", "onDestroy");629         mFileNames.clear();630         mFilePaths.clear();631         this.unregisterReceiver(mFileBroadcast);632         this.unregisterReceiver(mServiceBroadCast);633     }634     635     private String mAction;636     public static boolean isComeBackFromNotification = false;637     /**内部广播类*/638     class FileBroadcast extends BroadcastReceiver{639         @Override640         public void onReceive(Context context, Intent intent) {641             mAction = intent.getAction();642             // 搜索完毕的广播643             if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){644                 mFileNames = intent.getStringArrayListExtra("mFileNameList");645                 mFilePaths = intent.getStringArrayListExtra("mFilePathsList");646                 Toast.makeText(MainActivity.this, "搜索完毕!", Toast.LENGTH_SHORT).show();647                 //这里搜索完毕之后应该弹出一个弹出框提示用户要不要显示数据648                 searchCompletedDialog("搜索完毕,是否马上显示结果?");649                 getApplicationContext().stopService(serviceIntent);//当搜索完毕的时候停止服务,然后在服务中取消通知650             // 点击通知栏跳转过来的广播651             }else if(FileService.FILE_NOTIFICATION.equals(mAction)){//点击通知回到当前Activity,读取其中信息652                 String mNotification = intent.getStringExtra("notification");653                 Toast.makeText(MainActivity.this, mNotification, Toast.LENGTH_LONG).show();654                 searchCompletedDialog("你确定要取消搜索吗?");655             }656         }657     }658     659     //搜索完毕和点击通知过来时的提示框660     private void searchCompletedDialog(String message){661         Builder searchDialog = new AlertDialog.Builder(MainActivity.this)662         .setTitle("提示")663         .setMessage(message)664         .setPositiveButton("确定", new OnClickListener(){665             public void onClick(DialogInterface dialog,int which) {666                 //当弹出框时,需要对这个确定按钮进行一个判断,因为要对不同的情况做不同的处理(2种情况)667                 // 1.搜索完毕668                 // 2.取消搜索669                 if(FileService.FILE_SEARCH_COMPLETED.equals(mAction)){670                     if(mFileNames.size() == 0){671                         Toast.makeText(MainActivity.this, "无相关文件/文件夹!", Toast.LENGTH_SHORT).show();672                         setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths));//清空列表673                     }else{ 674                         //显示文件列表675                         setListAdapter(new FileAdapter(MainActivity.this,mFileNames,mFilePaths));676                     }677                 }else{678                     //设置搜索标志为true,679                     isComeBackFromNotification = true;680                     //关闭服务,取消搜索681                     getApplicationContext().stopService(serviceIntent);682                 }683             }684         })685         .setNegativeButton("取消", null);686         searchDialog.create();687         searchDialog.show();688     }689     690     691     692 693     class FileAdapter extends BaseAdapter{694         //返回键,各种格式的文件的图标695         private Bitmap mBackRoot;696         private Bitmap mBackUp;697         private Bitmap mImage;698         private Bitmap mAudio;699         private Bitmap mRar;700         private Bitmap mVideo;701         private Bitmap mFolder;702         private Bitmap mApk;703         private Bitmap mOthers;704         private Bitmap mTxt;705         private Bitmap mWeb;     706         private Context mContext;707         //文件名列表708         private List<String> mFileNameList;709         //文件对应的路径列表710         private List<String> mFilePathList;711       712         public FileAdapter(Context context,List<String> fileName,List<String> filePath){713             mContext = context;714             mFileNameList = fileName;715             mFilePathList = filePath;716             //初始化图片资源717             //返回到根目录718             mBackRoot = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_root);719             //返回到上一级目录720             mBackUp = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.back_to_up);721             //图片文件对应的icon722             mImage = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.image);723             //音频文件对应的icon724             mAudio = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.audio);725             //视频文件对应的icon726             mVideo = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.video);727             //可执行文件对应的icon728             mApk = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.apk);729             //文本文档对应的icon730             mTxt = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.txt);731             //其他类型文件对应的icon732             mOthers = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.others);733             //文件夹对应的icon734             mFolder = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.folder);735             //zip文件对应的icon736             mRar = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.zip_icon);737             //网页文件对应的icon738             mWeb = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.web_browser);739         }740         //获得文件的总数    741         @Override742         public int getCount() {743             return mFilePathList.size();744         }745         //获得当前位置对应的文件名746         @Override747         public Object getItem(int position) {748             return mFileNameList.get(position);749         }750         //获得当前的位置751         @Override752         public long getItemId(int position) {753             return position;754         }755         //获得视图756         @Override757         public View getView(int position, View convertView, ViewGroup viewgroup) {758             ViewHolder viewHolder = null;759             if (convertView == null) {760                 viewHolder = new ViewHolder();761                 LayoutInflater mLI = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);762                 //初始化列表元素界面763                 convertView = mLI.inflate(R.layout.list_child, null);764                 //获取列表布局界面元素765                 viewHolder.mIV = (ImageView)convertView.findViewById(R.id.image_list_childs);766                 viewHolder.mTV = (TextView)convertView.findViewById(R.id.text_list_childs);767                 //将每一行的元素集合设置成标签768                 convertView.setTag(viewHolder);769             } else {770                 //获取视图标签771                 viewHolder = (ViewHolder) convertView.getTag();772             }773             File mFile = new File(mFilePathList.get(position).toString());774             //如果                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   775             if(mFileNameList.get(position).toString().equals("BacktoRoot")){776                 //添加返回根目录的按钮777                 viewHolder.mIV.setImageBitmap(mBackRoot);778                 viewHolder.mTV.setText("返回根目录");779             }else if(mFileNameList.get(position).toString().equals("BacktoUp")){780                 //添加返回上一级菜单的按钮781                 viewHolder.mIV.setImageBitmap(mBackUp);782                 viewHolder.mTV.setText("返回上一级");783             }else if(mFileNameList.get(position).toString().equals("BacktoSearchBefore")){784                 //添加返回搜索之前目录的按钮785                 viewHolder.mIV.setImageBitmap(mBackRoot);786                 viewHolder.mTV.setText("返回搜索之前目录");787             }else{788                 String fileName = mFile.getName();789                 viewHolder.mTV.setText(fileName);790                 if(mFile.isDirectory()){791                     viewHolder.mIV.setImageBitmap(mFolder);792                 }else{793                     String fileEnds = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length()).toLowerCase();//取出文件后缀名并转成小写794                     if(fileEnds.equals("m4a")||fileEnds.equals("mp3")||fileEnds.equals("mid")||fileEnds.equals("xmf")||fileEnds.equals("ogg")||fileEnds.equals("wav")){795                         viewHolder.mIV.setImageBitmap(mVideo);796                     }else if(fileEnds.equals("3gp")||fileEnds.equals("mp4")){797                         viewHolder.mIV.setImageBitmap(mAudio);798                     }else if(fileEnds.equals("jpg")||fileEnds.equals("gif")||fileEnds.equals("png")||fileEnds.equals("jpeg")||fileEnds.equals("bmp")){799                         viewHolder.mIV.setImageBitmap(mImage);800                     }else if(fileEnds.equals("apk")){801                         viewHolder.mIV.setImageBitmap(mApk);802                     }else if(fileEnds.equals("txt")){803                         viewHolder.mIV.setImageBitmap(mTxt);804                     }else if(fileEnds.equals("zip")||fileEnds.equals("rar")){805                         viewHolder.mIV.setImageBitmap(mRar);806                     }else if(fileEnds.equals("html")||fileEnds.equals("htm")||fileEnds.equals("mht")){807                         viewHolder.mIV.setImageBitmap(mWeb);808                     }else {809                         viewHolder.mIV.setImageBitmap(mOthers);810                     }811                 }                812             }813             return convertView;814         }815         //用于存储列表每一行元素的图片和文本816         class ViewHolder {817             ImageView mIV;818             TextView mTV;819         }820         821         822     }823 824 825 826 }827 828     829     

MainActivity.java

 

 

package com.supermario.filemanager;import java.io.File;import java.util.ArrayList;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.os.Handler;import android.os.HandlerThread;import android.os.IBinder;import android.os.Looper;import android.os.Message;import android.util.Log;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.supermario.file.FILE_SEARCH_COMPLETED";    public static final String FILE_NOTIFICATION = "com.supermario.file.FILE_NOTIFICATION";        @Override    public IBinder onBind(Intent arg0) {        return null;    }        //创建服务    @Override    public void onCreate() {        super.onCreate();        Log.d("FileService", "file service is onCreate");        //新建处理线程        HandlerThread mHT = new HandlerThread("FileService",HandlerThread.NORM_PRIORITY);        mHT.start();        mLooper = mHT.getLooper();        mFileHandler = new FileHandler(mLooper);    }    //服务开始    @Override    public void onStart(Intent intent, int startId) {        super.onStart(intent, startId);        Log.d("FileService", "file service is onStart");        mFileName = new ArrayList<String>();        mFilePaths = new ArrayList<String>();        mFileHandler.sendEmptyMessage(0);        //发出通知表明正在进行搜索        fileSearchNotification();    }    @Override    public void onDestroy() {        super.onDestroy();        //取消通知        mNF.cancel(R.string.app_name);    }        class FileHandler extends Handler{                public FileHandler(Looper looper){            super(looper);        }                @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            Log.d("FileService", "file service is handleMessage");            //在指定范围搜索            initFileArray(new File(SearchBroadCast.mServiceSearchPath));            //当用户点击了取消搜索则不发生广播            if(!MainActivity.isComeBackFromNotification == true){                Intent intent = new Intent(FILE_SEARCH_COMPLETED);                intent.putStringArrayListExtra("mFileNameList", mFileName);                intent.putStringArrayListExtra("mFilePathsList", mFilePaths);                //搜索完毕之后携带数据并发送广播                sendBroadcast(intent);            }        }        }        private int m = -1;    /**具体做搜索事件的可回调函数*/    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(SearchBroadCast.mServiceKeyword) != -1){                    if (m == -1) {                        m++;                        // 返回搜索之前目录                        mFileName.add("BacktoSearchBefore");                        mFilePaths.add(MainActivity.mCurrentFilePath);                    }                    mFileName.add(currentArray.getName());                    mFilePaths.add(currentArray.getPath());                }                //如果是文件夹则回调该方法                if(currentArray.exists()&&currentArray.isDirectory()){                    //如果用户取消了搜索,应该停止搜索的过程                    if(MainActivity.isComeBackFromNotification == true){                        return;                    }                    initFileArray(currentArray);                }            }        }                                                                                                                                                                                                                                                                                                                                                                                                }        NotificationManager mNF;    /**通知*/    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, "在"+SearchBroadCast.mServiceSearchPath+"下搜索", "搜索关键字为"+SearchBroadCast.mServiceKeyword+"【点击可取消搜索】", mPI);        if(mNF == null){            mNF = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);        }        mNF.notify(R.string.app_name, mNotification);    }  }

FileService.JAVA  搜索服务

 

 

package com.supermario.filemanager;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;public class SearchBroadCast 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");        }    }}

SearchBroadCast.JAVA

 

文件管理器