• 文件管理器


      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  搜索服务

    源文件下载

  • 相关阅读:
    SPOJ1007 VLATTICE
    hdu 4746Mophues[莫比乌斯反演]
    [Offer收割]编程练习赛13 B.最大子矩阵[枚举]
    [SCOI2011]飞镖[数学模拟]
    2333: [SCOI2011]棘手的操作[离线线段树]
    hdu3507 Print Article[斜率优化dp入门题]
    react 日期
    使用arc进行code review
    css冲突2 要关闭的css在项目代码以外,但是是通过<link>标签引入的css(例如bootstrap):解决方法,在APP.css中使用全局样式
    <svg>标签
  • 原文地址:https://www.cnblogs.com/hixin/p/4098299.html
Copyright © 2020-2023  润新知