Android6.0 CMFileManager文件管理器源码分析-文件分类与文件操作

Android6.0 CMFileManager文件管理器源码分析-文件分类与文件操作

一、主要内容:

如何学习一个新的模块:学习新模块时主要通过如下3个方面来学习,以CMFileManager文件管理器为例:

1、模块源码目录结构、界面

2、模块入口(清单文件)

3、模块主要功能(文件分类、文件操作<删除、粘贴、复制、剪切、重命名>)

二、模块目录结构及主界面

1、目录结构

2、主界面

 

 

3、功能类关系图

此图只是大致描述下文件操作涉及到的类之间的跳转流程,不是规范的流程图、类图

三、模块入口

清单文件:

AndroidManifest.xml//清单文件是看一个陌生模块的入口,通过清单文件可以了解此模块大致的功能

 1 <activity
 2 
 3 android:name="com.cyanogenmod.filemanager.activities.LoadActivity"
 4 
 5 android:theme="@style/FileManager.Theme.Material.NoActionBar"
 6 
 7 android:screenOrientation="portrait">
 8 
 9      <intent-filter>
10 
11        <action android:name="android.intent.action.MAIN" />
12 
13        <category android:name="android.intent.category.LAUNCHER" />
14 
15      </intent-filter>
16 
17 </activity>

 

LoadActivity.java

 1 TimerTask task = new TimerTask() {
 2 
 3      @Override
 4 
 5      public void run() {
 6 
 7          initsharedPreferences();
 8 
 9          if(mShared.getBoolean("First", true)){
10 
11          mEditor.putBoolean("First", false);
12 
13          mEditor.commit();
14 
15          initFileTime();
16 
17         }
18 
19     mEditor.putInt("limitCount", 0);
20 
21     mEditor.commit();
22 
23     Intent intent = new Intent(LoadActivity.this,NavigationActivity.class);
24 
25     startActivity(intent);
26 
27     finish();
28 
29     }
30 
31 };

 

 

四、文件分类代码分析

1、onCreate

 1 @Override
 2 
 3 protected void onCreate(Bundle state) {
 4 
 5  6 
 7 getMimeTypes();//根据文件扩展名获取文件类型(判断其属于image,audio等)
 8 
 9 initNavigationViews();//初始化文件管理器首界面(9个方块的界面)
10 
11 12 
13 }

2、onResume

 1 @Override
 2 
 3 protected void onResume() {
 4 
 5  6 
 7 /*modify by zh start*/
 8 
 9         isExternalSdMounted = isExternalStorageMounted();
10 
11         initSdpath();
12 
13                   
14 
15         /*modifystart*/
16 
17         if (mCountTask != null) {
18 
19            mCountTask.cancel(true);
20 
21         }
22 
23          /*modif5 end*/  
24 
25         mCountTask = new SearchCountAsyncTask();//异步任务,用来对不同种类的文件进行计数
26 
27         mCountTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
28 
29         mSizeTask = new SearchSizeAsyncTask();
30 
31         if(!isExternalSdMounted){
32 
33                  mSizeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,new String[]{DEFAULT_PATH});
34 
35                  visibleSdcard.setVisibility(View.GONE);
36 
37         }else{
38 
39                  visibleSdcard.setVisibility(View.VISIBLE);
40 
41                    EXTERNAL_SDCARD_PATH = StorageHelper.getPhoneSDPath(this);    
42 
43                  mSizeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,new String[]{DEFAULT_PATH,EXTERNAL_SDCARD_PATH});
44 
45         }
46 
47          /*modify31 end*/
48 
49              if(!mPassOnCreate) {
50 
51                        if(mCountTask != null) {
52 
53                                 mCountTask.canceled = true;
54 
55                                 mCountTask.cancel(true);
56 
57                        }
58 
59                        mCountTask = new SearchCountAsyncTask();
60 
61                        mCountTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
62 
63              }
64 
65             
66 
67         if (mSearchView.getVisibility() == View.VISIBLE) {
68 
69             closeSearch();
70 
71         }
72 
73 74 
75 }

 

3、getMimeTypes

 1 void getMimeTypes(){//读取配置文件来判断文件属于哪一类(比如对于读取到的.jpg,.png属于image)
 2         try {
 3             Properties mimeTypes = new Properties();
 4             mimeTypes.load(this.getResources().openRawResource(R.raw.mime_types));
 5             Enumeration<Object> e = mimeTypes.keys();
 6             while (e.hasMoreElements()) {
 7                 String extension = (String)e.nextElement();
 8                 String data = mimeTypes.getProperty(extension);
 9                 String[] datas = data.split(",");
10                 for (String theData : datas) {
11                     String[] mimeData = theData.split("\\|"); //$NON-NLS-1$
12 
13                     if(mimeData[0].toString().trim().equalsIgnoreCase(MimeTypeCategory.APP.toString())){
14                         app.add(extension);
15                     }else if(mimeData[0].toString().trim().equalsIgnoreCase(MimeTypeCategory.AUDIO.toString())){
16                         audio.add(extension);
17                     }
18 19                 }
20 
21             } 
22         }catch (Exception e2) {
23             // TODO: handle exception
24         }
25     }

 


4、initNavigationViews

 1 private void initNavigationViews() {
 2         //Get the navigation views (wishlist: multiple view; for now only one view)
 3         this.mNavigationViews = new NavigationView[1];
 4         this.mCurrentNavigationView = 0;
 5         this.mNavigationViews[0] = (NavigationView)findViewById(R.id.navigation_view);
 6         this.mNavigationViews[0].setId(0);
 7         this.mEasyModeListView = (GridView) findViewById(R.id.lv_easy_mode);
 8         this.mEasyModeListView.setVisibility(View.VISIBLE);
 9         mEasyModeAdapter = new ArrayAdapter<MimeTypeCategory>(this, R.layout.navigation_view_simple_item2) {
10             @Override
11             public View getView(int position, View convertView, ViewGroup parent) {
12                 convertView = (convertView == null) ?getLayoutInflater().inflate(R.layout.navigation_view_simple_item2, parent, false) : convertView;
13                 MimeTypeCategory item = getItem(position);
14                 String typeTitle = MIME_TYPE_LOCALIZED_NAMES[item.ordinal()];
15                 TextView typeTitleTV = (TextView) convertView.findViewById(R.id.navigation_text);
16 17                 if(parent.getChildCount()==position){
18                     switch (position) {
19                     case 0:
20                         limitPostion++;
21                         if(limitPostion>1) break;
22                         if(mCountTask.countTaskFlag){
23                             int sharedCount = getSharedCount("news",mCountTask.mCount.newCount);
24                             textCount.setText("(" + sharedCount + ")");
25                         }else{
26                             savaSdcardOrinternar("news",mCountTask.mCount.newCount);
27                             textCount.setText("(" + mCountTask.mCount.newCount + ")");
28                         }
29                         Log.e("zqq","news");
30                         break;
31                     case 1:
32                         if(mCountTask.countTaskFlag){
33                             int sharedCount = getSharedCount("apps",mCountTask.mCount.appCount);
34                             textCount.setText("("+sharedCount+")");
35                         }else{
36                             textCount.setText("("+mCountTask.mCount.appCount+")");
37                             savaSdcardOrinternar("apps",mCountTask.mCount.appCount);
38                         }
39                         Log.e("zqq","apps");
40                         break;
41 42                     default:
43                         textCount.setText("0");
44                         break;
45                     }
46                 }
47                 if(null != mEditor) {
48                     mEditor.commit();
49                 }
50                 typeTitleTV.setText(typeTitle);
51                 typeIconIV.setImageDrawable(EASY_MODE_ICONS.get(item));
52                 convertView.setOnClickListener(mEasyModeItemClickListener);
53                 convertView.setTag(position);
54                 return convertView;
55             }
56 
57         };

 

5、initSdpath

1 private void initSdpath() {
2         pathList.clear(); /*modify 331*/
3         pathList.add(FileHelper.INNER_SDCARD_DIRECTORY);
4         if(isExternalSdMounted) {
5             /*modify start*/    
6             pathList.add(StorageHelper.getPhoneSDPath(this)/*FileHelper.EXTERNAL_SDCARD_DIRECTORY*/);
7             /*modifyer end*/
8         }
9     }

 

6、SearchAllFileCount

 1 void SearchAllFileCount(SearchCountAsyncTask task){
 2         if(this.canceled) return;
 3         for (String path : pathList) {//pathList是list集合,值为 /storage/sdcard0 , /storage/sdcard1
 4             if(null == path) continue;
 5             File[] files = new File(path).listFiles();
 6             if(null == files) {
 7                 continue ;
 8             }
 9             for (int i = 0; i < files.length; i++) {
10                 File f = files[i];
11                 if(null == f) continue;
12                 if(f.isFile()&&!(f.getName().substring(0,1).contains("."))){
13                     FileSystemObject fso = FileHelper
14                             .createFileSystemObject(files[i]); //FileSystemObject封装了文件的属性
15                     if(!timeFilter(fso)){//根据文件距上次修改时间的大小判断是否为最新文件                               task.mCount.newCount ++ ;
16                     }
17 
18                     String ext = FileHelper.getExtension(fso);
19                     if("3gp".equals(ext) || "3gpp".equals(ext) || "3g2".equals(ext) || "3gpp2".equals(ext)) {
20                         String category = MimeTypeHelper.getCategory(NavigationActivity.this, fso).toString();
21                         if("AUDIO".equals(category)) {
22                             task.mCount.audioCount ++;
23                             continue;
24                         } else if ("VIDEO".equals(category)) {
25                             task.mCount.voideoCount ++;
26                             continue;
27                         }
28                     }
29 30                     for (int j = 0; j < audio.size(); j++) {
31                         if(f.getName().substring(f.getName().lastIndexOf(".")+1).
32                                 equalsIgnoreCase(audio.get(j).toString())){
33                             task.mCount.audioCount ++;
34                         }
35                     }
36 37                     for (int j = 0; j < image.size(); j++) {
38                         if(f.getName().substring(f.getName().lastIndexOf(".")+1).
39                                 equalsIgnoreCase(image.get(j).toString())){
40                             task.mCount.imageCount ++;
41                         }
42                     }
43                 }else if (f.isDirectory() && f.getPath().indexOf("/.") == -1)//如果是目录(排除隐藏文件、隐藏文件夹)
44                     SearchFileCount(f.getPath(),task);
45             }
46         }
47     }
48 
49     void SearchFileCount(String path,SearchCountAsyncTask task){
50         if(this.canceled) return;
51         File[] files = new File(path).listFiles();
52         if(null == files) return ;
53         for (int i = 0; i < files.length; i++) {
54             File f = files[i];
55             if(null == f) continue;
56             if(f.isFile()&&!(f.getName().substring(0,1).contains("."))){
57                 FileSystemObject fso = FileHelper
58                         .createFileSystemObject(files[i]);
59                 if(!timeFilter(fso)){
60                     task.mCount.newCount ++ ;
61                 }
62                 String ext = FileHelper.getExtension(fso);
63                 if("3gp".equals(ext) || "3gpp".equals(ext) || "3g2".equals(ext) || "3gpp2".equals(ext)) {
64                     String category = MimeTypeHelper.getCategory(NavigationActivity.this, fso).toString();
65                     if("AUDIO".equals(category)) {
66                         task.mCount.audioCount ++;
67                         continue;
68                     } else if ("VIDEO".equals(category)) {
69                         task.mCount.voideoCount ++;
70                         continue;
71                     }
72                 }
73 74                 for (int j = 0; j < audio.size(); j++) {
75                     if(f.getName().substring(f.getName().lastIndexOf(".")+1).
76                             equalsIgnoreCase(audio.get(j).toString())){
77                         task.mCount.audioCount ++;
78                     }
79                 }
80 81                 for (int j = 0; j < image.size(); j++) {
82                     if(f.getName().substring(f.getName().lastIndexOf(".")+1).
83                             equalsIgnoreCase(image.get(j).toString())){
84                         task.mCount.imageCount ++;
85                     }
86                 }
87             }else if (f.isDirectory() && f.getPath().indexOf("/.") == -1)
88                 SearchFileCount(f.getPath(),task);//递归调用分类不同的文件
89         }
90     }
91 }

 

7、getCategory

public static final MimeTypeCategory getCategory(Context context, FileSystemObject fso) {
        // Ensure that have a context
//Get the extension and delivery
        final MimeTypeCategory category = getCategoryFromExt(context,
                FileHelper.getExtension(fso), fso.getFullPath());
        // Check  system file
        if (category == MimeTypeCategory.NONE && fso instanceof SystemFile) {
            return MimeTypeCategory.SYSTEM;
        }
        return category;
    }

    public static final MimeTypeCategory getCategoryFromExt(Context context, String ext, String absolutePath) {
        …
        if (ext != null) {
            //Load from the database of mime types
            MimeTypeInfo mimeTypeInfo = getMimeTypeInternal(absolutePath, ext);
            if (mimeTypeInfo != null) {
                return mimeTypeInfo.mCategory;
            }
        }
        …
    }


    private static final MimeTypeInfo getMimeTypeInternal(String absolutePath, String ext) {
        MimeTypeInfo mimeTypeInfo = null;
        ArrayList<MimeTypeInfo> mimeTypeInfoList = sMimeTypes.get(ext.toLowerCase(Locale.ROOT));
        // Multiple mimetypes map to the same extension, try to resolve it.
        if (mimeTypeInfoList != null && mimeTypeInfoList.size() > 1) {
            if (absolutePath != null) {
                String mimeType = getAmbiguousExtensionMimeType(absolutePath, ext);
                mimeTypeInfo = sExtensionMimeTypes.get(ext + mimeType);
            } else {
                // We don't have the ability to read the file to resolve the ambiguity,
                // so default to the first available mimetype.
                mimeTypeInfo = mimeTypeInfoList.get(0);//NONE
            }
        } else if (mimeTypeInfoList != null && mimeTypeInfoList.size() == 1) {
            // Only one possible mimetype, so pick that one.
            mimeTypeInfo = mimeTypeInfoList.get(0);
        }
        return mimeTypeInfo;
    }



    private static final String getAmbiguousExtensionMimeType(String absolutePath, String ext) {
        if (AmbiguousExtensionHelper.AMBIGUOUS_EXTENSIONS_MAP.containsKey(ext)) {
            AmbiguousExtensionHelper helper =
                    AmbiguousExtensionHelper.AMBIGUOUS_EXTENSIONS_MAP.get(ext);
            String mimeType = helper.getMimeType(absolutePath, ext); //返回video/3gpp或者audio/3gpp、video/3gpp2、audio/3gpp3、
            if (!TextUtils.isEmpty(mimeType)) {
                return mimeType;
            }
        }
        return null;
    }


    public String getMimeType(String absolutePath, String extension) {
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();//
        try {
            retriever.setDataSource(absolutePath);
            boolean hasVideo =
                    retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO) !=
                    null;//调用native方法去触探文件是音频还是视频
                    if (is3GPP(extension)) {
                        return hasVideo ? VIDEO_3GPP_MIME_TYPE : AUDIO_3GPP_MIME_TYPE;
                    } else if (is3GPP2(extension)) {
                        return hasVideo ? VIDEO_3GPP2_MIME_TYPE : AUDIO_3GPP2_MIME_TYPE;
                    }
        } catch (RuntimeException e) {
            Log.e(TAG, "Unable to open 3GP file to determine mimetype");
        }
        // Default to video 3gp if the file is unreadable as this was the default before
        // ambiguous resolution support was added.
        return VIDEO_3GPP_MIME_TYPE;
    }

 

五、文件操作

1、文件操作总括

 1 public void guiAction(View v) {
 2         openActionsDialog(getCurrentNavigationView().getCurrentDir(), true);
 3         switch (v.getId()) {
 4         case R.id.gui_deletes://删除
 5             android.util.Log.i("wangqx","gui_deletes");
 6             if (ActionsDialog.mOnSelectionListener != null) {
 7                 List<FileSystemObject> selection = ActionsDialog.mOnSelectionListener
 8                         .onRequestSelectedFiles();
 9                 DeleteActionPolicy.removeFileSystemObjects(this, selection,
10                         ActionsDialog.mOnSelectionListener,
11                         ActionsDialog.mOnRequestRefreshListener, null);
12             }
13             break;
14 
15         case R.id.gui_cuts://剪切
16             android.util.Log.i("wangqx","gui_cuts");
17             fileCutOrCopy = 1;
18             pasteAction.setVisibility(View.VISIBLE);
19             hiddenPopupWindowActionBar();
20             hiddenActionBarSetting();
21             //            if(viewPopupButtom.getVisibility()==View.GONE){
22             //            getCurrentNavigationView().onDeselectItem();
23             //            }
24             break;
25         case R.id.gui_copys://复制
26             android.util.Log.i("wangqx","gui_copys");
27             fileCutOrCopy = 2;
28             pasteAction.setVisibility(View.VISIBLE);
29             hiddenPopupWindowActionBar();
30             hiddenActionBarSetting();
31             //            if(viewPopupButtom.getVisibility()==View.GONE){
32             //            getCurrentNavigationView().onDeselectItem();
33             //            }
34             break;
35         case R.id.action_paste://粘贴
36             android.util.Log.i("wangqx","action_paste");
37             Log.i("hewei", "fileCutOrCopy ===" + fileCutOrCopy);
38             if (fileCutOrCopy == 1) {// Cut
39                 if (ActionsDialog.mOnSelectionListener != null) {
40                     if (finishFlag) {
41                         CopyMoveActionPolicy.moveFileSystemObjects(this,
42                                 ActionsDialog.createLinkedResource(SearchActivity.fosList, fso),
43                                 ActionsDialog.mOnSelectionListener,
44                                 ActionsDialog.mOnRequestRefreshListener);
45                         SearchActivity.fosList.clear();
46                     } else {
47                         List<FileSystemObject> selection = ActionsDialog.mOnSelectionListener
48                                 .onRequestSelectedFiles();
49                         CopyMoveActionPolicy.moveFileSystemObjects(this,
50                                 ActionsDialog.createLinkedResource(selection, fso),
51                                 ActionsDialog.mOnSelectionListener,
52                                 ActionsDialog.mOnRequestRefreshListener);
53                     }
54                     finishFlag = false ;
55                     fileCutOrCopy = 0 ;
56                 }
57             } else if (fileCutOrCopy == 2) {// Copy
58                 if (ActionsDialog.mOnSelectionListener != null) {
59                     if (finishFlag) {
60                         CopyMoveActionPolicy.copyFileSystemObjects(this,
61                                 ActionsDialog.createLinkedResource(SearchActivity.fosList, fso),
62                                 ActionsDialog.mOnSelectionListener,
63                                 ActionsDialog.mOnRequestRefreshListener);
64                         SearchActivity.fosList.clear();
65                         finishFlag = false ;
66                         fileCutOrCopy = 0 ;
67                     } else {
68                         List<FileSystemObject> selection = ActionsDialog.mOnSelectionListener
69                                 .onRequestSelectedFiles();
70                         CopyMoveActionPolicy.copyFileSystemObjects(this,
71                                 ActionsDialog.createLinkedResource(selection, fso),
72                                 ActionsDialog.mOnSelectionListener,
73                                 ActionsDialog.mOnRequestRefreshListener);
74                     }
75                     finishFlag = false ;
76                     fileCutOrCopy = 0 ;
77                 }
78             }
79             hiddenActionPaste();
80             break;
81         case R.id.action_rename://重命名
82             if (ActionsDialog.mOnSelectionListener != null) {
83                 TextView menuItemView = (TextView)viewPopupButtom.findViewById(R.id.action_rename);
84                 dialog.showFsoInputNameDialog(menuItemView, this.newFso, false);
85                 selectAll.setImageResource(R.drawable.ic_new_gui_select_all);
86                 hiddenPopupWindowActionBar();
87                 if(viewPopupButtom.getVisibility()==View.GONE){
88                     getCurrentNavigationView().onDeselectAll();
89                 }
90                 return;
91             }
92             break;
93         default:
94             break;
95         }
96     }

 

2、删除:

1>、removeFileSystemObjects
 1 public static void removeFileSystemObjects(
 2             final Context ctx, final List<FileSystemObject> files,
 3             final OnSelectionListener onSelectionListener,
 4             final OnRequestRefreshListener onRequestRefreshListener,
 5             final OnItemFlingerResponder onItemFlingerResponder) {
 6         Log.i(TAG, files.size()+"----++++---");
 7         // Ask the user before remove
 8         AlertDialog dialog = DialogHelper.createYesNoDialog(
 9                 ctx,
10                 R.string.confirm_deletion,
11                 R.string.actions_ask_undone_operation_msg,
12                 new DialogInterface.OnClickListener() {
13                     @Override
14                     public void onClick(DialogInterface alertDialog, int which) {
15                         if (which == DialogInterface.BUTTON_POSITIVE) {
16                             // Remove the items
17                             removeFileSystemObjectsInBackground(
18                                     ctx,
19                                     files,
20                                     onSelectionListener,
21                                     onRequestRefreshListener,
22                                     onItemFlingerResponder);
23                             // SearchActivity.fosList.clear();
24                         } 
25 26                         //SearchActivity.mEditMode = false;
27                     }
28                 }
29     });
30         DialogHelper.delegateDialogShow(ctx, dialog);
31 }

 


2>、removeFileSystemObjectsInBackground
 1 static void removeFileSystemObjectsInBackground(
 2             final Context ctx, final List<FileSystemObject> files,
 3             final OnSelectionListener onSelectionListener,
 4             final OnRequestRefreshListener onRequestRefreshListener,
 5             final OnItemFlingerResponder onItemFlingerResponder) {
 6  7         // 2.- Sort the items by path to avoid delete parents fso prior to child fso
 8         final List<FileSystemObject> sortedFsos = new ArrayList<FileSystemObject>(files);
 9         Collections.sort(sortedFsos, new Comparator<FileSystemObject>() {
10             @Override
11             public int compare(FileSystemObject lhs, FileSystemObject rhs) {
12                 return lhs.compareTo(rhs) * -1; //Reverse
13             }
14         });
15 
16         // The callable interface
17         final BackgroundCallable callable = new BackgroundCallable() {
18             // The current items
19             private int mCurrent = 0;
20             final Context mCtx = ctx;
21             final List<FileSystemObject> mFiles = sortedFsos;
22             final OnRequestRefreshListener mOnRequestRefreshListener = onRequestRefreshListener;
23 
24             final Object mSync = new Object();
25             Throwable mCause;
26 
27 28 
29             @Override
30             public Spanned requestProgress() {
31                 FileSystemObject fso = this.mFiles.get(this.mCurrent);
32 
33                 // Return the current operation
34                 String progress =
35                         this.mCtx.getResources().
36                         getString(
37                                 R.string.waiting_dialog_deleting_msg,
38                                 fso.getFullPath());
39                 return Html.fromHtml(progress);
40             }
41 42             @Override
43             public void doInBackground(Object... params) throws Throwable {
44                 this.mCause = null;
45 
46                 // This method expect to receive
47                 // 1.- BackgroundAsyncTask
48                 BackgroundAsyncTask task = (BackgroundAsyncTask)params[0];
49 
50                 int cc = this.mFiles.size();
51                 for (int i = 0; i < cc; i++) {
52                     FileSystemObject fso = this.mFiles.get(i);
53                     doOperation(this.mCtx, fso);
54                     // Next file
55                     this.mCurrent++;
56                     if (this.mCurrent < this.mFiles.size()) {
57                         task.onRequestProgress();
58                     }
59                 }
60             }

 

3>、doOperation
 1 /**
 2      * Method that deletes the file or directory
 3      *
 4      * @param ctx The current context
 5      * @param fso The file or folder to be deleted
 6      */
 7     private void doOperation(
 8             final Context ctx, final FileSystemObject fso) throws Throwable {
 9         try {
10             // Remove the item
11             if (FileHelper.isDirectory(fso)) {
12                 CommandHelper.deleteDirectory(ctx, fso.getFullPath(), null);
13             } else {
14                 CommandHelper.deleteFile(ctx, fso.getFullPath(), null);
15             }
16 17         } 
18     }
19 20 };
21 final BackgroundAsyncTask task = new BackgroundAsyncTask(ctx, callable);
22 
23 // Execute background task
24 task.execute(task);
25 }

 

4>、deleteFile
 1 public static boolean deleteFile(Context context, String file, Console console)
 2             throws FileNotFoundException, IOException, ConsoleAllocException,
 3             NoSuchFileOrDirectory, InsufficientPermissionsException,
 4             CommandNotFoundException, OperationTimeoutException,
 5             ExecutionException, InvalidCommandDefinitionException, ReadOnlyFilesystemException,
 6             CancelledOperationException {
 7         Console c = ensureConsoleForFile(context, console, file);
 8         DeleteFileExecutable executable =
 9                 c.getExecutableFactory().newCreator().createDeleteFileExecutable(file);
10         writableExecute(context, executable, c);
11 
12         // Remove from mediascanner
13         MediaScannerConnection.scanFile(context, new String[]{
14                 MediaHelper.normalizeMediaPath(file)
15         }, null, null);
16 
17         return executable.getResult().booleanValue();
18     }

 

5>、execute
 1 DeleteFileExecutable createDeleteFileExecutable(String file) throws CommandNotFoundException,
 2     NoSuchFileOrDirectory, InsufficientPermissionsException;
 3     DeleteFileExecutable 是一个接口类。//接口或者抽象类,就看实现类(子类)
 4     DeleteFileCommend.java
 5     @Override
 6     public void execute()
 7             throws InsufficientPermissionsException, NoSuchFileOrDirectory, ExecutionException {
 8         if (isTrace()) {
 9             Log.v(TAG,
10                     String.format("Deleting file: %s", this.mPath)); //$NON-NLS-1$
11         }
12         File f = new File(this.mPath);
13 14         // Delete the file
15         if (!f.delete()) {
16             if (isTrace()) {
17                 Log.v(TAG, "Result: FAIL. InsufficientPermissionsException"); //$NON-NLS-1$
18             }
19             throw new InsufficientPermissionsException();
20         }
21 22     }

 

3、剪切、复制、粘贴、重命名

1>、showFsoInputNameDialog
 1 public void showFsoInputNameDialog(final View v,
 2             final FileSystemObject fso, final boolean allowFsoName) {
 3         android.util.Log.i("wangqx", "showFsoInputNameDialog");
 4         TextView text = (TextView) v;
 5         // Hide the dialog
 6         this.mDialog.hide();
 7         // Show the input name dialog
 8         final InputNameDialog inputNameDialog = new InputNameDialog(
 9                 this.mContext,
10                 this.mOnSelectionListener.onRequestCurrentItems(), fso,
11                 allowFsoName, text.getText().toString().trim());
12         inputNameDialog
13         .setOnCancelListener(new DialogInterface.OnCancelListener() {
14             @Override
15             public void onCancel(DialogInterface dialog) {
16                 // Show the menu again
17                 // DialogHelper.delegateDialogShow(
18                 // ActionsDialog.this.mContext,
19                 // ActionsDialog.this.mDialog);
20             }
21         });
22         inputNameDialog
23         .setOnDismissListener(new DialogInterface.OnDismissListener() {
24             @Override
25             public void onDismiss(DialogInterface dialog) {
26                 android.util.Log.i("wangqx", "onDismiss8888888888");
27                 // Retrieve the name an execute the action
28                 try {
29                     String name = inputNameDialog.getName();
30                     Log.i(TAG, inputNameDialog.mFso.getName()+"inputNameDialog.mFso.getName()");
31                     switch (v.getId()) {
32                     case R.id.action_rename:
33                         android.util.Log.i("wangqx", "R.id.action_rename:");
34                         // Rename the fso
35                         if (ActionsDialog.this.mOnSelectionListener != null) {
36                             CopyMoveActionPolicy
37                             .renameFileSystemObject(
38                                     ActionsDialog.this.mContext,
39                                     inputNameDialog.mFso,
40                                     name,
41                                     ActionsDialog.this.mOnSelectionListener,
42                                     ActionsDialog.this.mOnRequestRefreshListener);
43                         }
44                         break;
45 46                     default:
47                         break;
48                     }
49                 } finally {
50                     ActionsDialog.this.mDialog.dismiss();
51                 }
52             }
53         });
54         inputNameDialog.show();
55     }

 


2>、moveFileSystemObjects
 1 public static void moveFileSystemObjects(
 2             final Context ctx,
 3             final List<LinkedResource> files,
 4             final OnSelectionListener onSelectionListener,
 5             final OnRequestRefreshListener onRequestRefreshListener) {
 6         // Internal move
 7         copyOrMoveFileSystemObjects(
 8                 ctx,
 9                 COPY_MOVE_OPERATION.MOVE,
10                 files,
11                 onSelectionListener,
12                 onRequestRefreshListener);
13     }

 


3>、copyOrMoveFileSystemObjects
  1 private static void copyOrMoveFileSystemObjects(
  2             final Context ctx,
  3             final COPY_MOVE_OPERATION operation,
  4             final List<LinkedResource> files,
  5             final OnSelectionListener onSelectionListener,
  6             final OnRequestRefreshListener onRequestRefreshListener) {
  7         // Some previous checks prior to execute
  8         ...
  9         // 3.- Check the operation consistency
 10         if (operation.compareTo(COPY_MOVE_OPERATION.MOVE) == 0) {
 11             if (!checkMoveConsistency(ctx, files, currentDirectory)) {
 12                 return;
 13             }
 14         }
 15 
 16         // The callable interface
 17         final BackgroundCallable callable = new BackgroundCallable() {
 18             // The current items
 19             private int mCurrent = 0;
 20             final Context mCtx = ctx;
 21             final COPY_MOVE_OPERATION mOperation = operation;
 22             final List<LinkedResource> mFiles = files;
 23             final OnRequestRefreshListener mOnRequestRefreshListener = onRequestRefreshListener;
 24 
 25             final Object mSync = new Object();
 26             Throwable mCause;
 27 
 28 
 29 
 30             @Override
 31             public Spanned requestProgress() {
 32                 File src = this.mFiles.get(this.mCurrent).mSrc;
 33                 File dst = this.mFiles.get(this.mCurrent).mDst;
 34 
 35                 // Return the current operation
 36                 String progress =
 37                         this.mCtx.getResources().
 38                         getString(
 39                                 this.mOperation.compareTo(COPY_MOVE_OPERATION.MOVE) == 0 ||
 40                                 this.mOperation.compareTo(COPY_MOVE_OPERATION.RENAME) == 0 ?
 41                                         R.string.waiting_dialog_moving_msg :
 42                                             R.string.waiting_dialog_copying_msg,
 43                                             src.getAbsolutePath(),
 44                                             dst.getAbsolutePath());
 45                 return Html.fromHtml(progress);
 46             }
 47 
 48             private void refreshUIAfterCompletion() {
 49                 // Remove orphan bookmark paths
 50 
 51                 if (files != null && (this.mOperation.compareTo(COPY_MOVE_OPERATION.MOVE) == 0 ||
 52                         this.mOperation.compareTo(COPY_MOVE_OPERATION.RENAME) == 0)) {
 53                     for (LinkedResource linkedFiles : files) {
 54                         Bookmarks.deleteOrphanBookmarks(ctx, linkedFiles.mSrc.getAbsolutePath());
 55                     }
 56                 }
 57                 //Operation complete. Refresh
 58                 if (this.mOnRequestRefreshListener != null) {
 59                     // The reference is not the same, so refresh the complete navigation view
 60                     this.mOnRequestRefreshListener.onRequestRefresh(null, true);
 61                 }
 62             }
 63 
 64             @Override
 65             public void onSuccess() {
 66                 refreshUIAfterCompletion();
 67                 ActionsPolicy.showOperationSuccessMsg(ctx);
 68             }
 69 
 70             @Override
 71             public void doInBackground(Object... params) throws Throwable {
 72                 this.mCause = null;
 73 
 74                 // This method expect to receive
 75                 // 1.- BackgroundAsyncTask
 76                 BackgroundAsyncTask task = (BackgroundAsyncTask)params[0];
 77 
 78                 int cc2 = this.mFiles.size();
 79                 for (int i = 0; i < cc2; i++) {
 80                     File src = this.mFiles.get(i).mSrc;
 81                     File dst = this.mFiles.get(i).mDst;
 82                     doOperation(this.mCtx, src, dst, this.mOperation);
 83                     // Next file
 84                     this.mCurrent++;
 85                     if (this.mCurrent < this.mFiles.size()) {
 86                         task.onRequestProgress();
 87                     }
 88                     //add by hewei for JIRA [21]
 89                     Uri uri = Uri.fromFile(dst);
 90                     Intent intent = new Intent("com.android.fileexplorer.action.MEDIA_SCANNER_SCAN_ALL");
 91                     intent.setData(uri);
 92                     ctx.sendBroadcast(intent);
 93                     //end by hewei for JIRA [21]
 94                 }
 95             }
 96             ...
 97             private void doOperation(
 98                     Context ctx, File src, File dst, COPY_MOVE_OPERATION operation)
 99                             throws Throwable {
100                 // If the source is the same as destiny then don't do the operation
101                 if (src.compareTo(dst) == 0) return;
102 
103                 try {
104                     // Be sure to append a / if source is a folder (otherwise system crashes
105                     // under using absolute paths) Issue: CYAN-2791
106                     String source = src.getAbsolutePath() +
107                             (src.isDirectory() ? File.separator : "");
108                     String dest = dst.getAbsolutePath() +
109                             (dst.isDirectory() ? File.separator : "");
110 
111                     /*
112             There is a possibility that the src and dst can have different consoles.
113             A possible case:
114             - src is from sd card and dst is secure storage
115             This could happen with anything that goes from a real console to a virtual
116             console or visa versa. Here we grab a handle on the console such that we
117             may explicitly kill the actions happening in both consoles.
118                      */
119                     // Need to derive the console for the source
120 
121                     mSrcConsole = CommandHelper.ensureConsoleForFile(ctx, null, source);
122                     // Need to derive the console for the destination
123                     mDstConsole = CommandHelper.ensureConsoleForFile(ctx, null, dest);
124 
125                     // Copy or move?
126                     if (operation.compareTo(COPY_MOVE_OPERATION.MOVE) == 0 ||
127                             operation.compareTo(COPY_MOVE_OPERATION.RENAME) == 0) {
128                         CommandHelper.move(
129                                 ctx,
130                                 source,
131                                 dst.getAbsolutePath(),
132                                 mSrcConsole);
133                     } else {
134                         CommandHelper.copy(
135                                 ctx,
136                                 source,
137                                 dst.getAbsolutePath(),
138                                 mSrcConsole);
139                     }
140                 } 
141                 ...
142                 // Check that the operation was completed retrieving the fso modified
143                 FileSystemObject fso =
144                 CommandHelper.getFileInfo(ctx, dst.getAbsolutePath(), false, null);
145                 if (fso == null) {
146                     throw new NoSuchFileOrDirectory(dst.getAbsolutePath());
147                 }
148             }
149             @Override
150             public void onFailRefresh() {
151 
152             }
153         };
154         final BackgroundAsyncTask task = new BackgroundAsyncTask(ctx, callable);
155 
156         // Prior to execute, we need to check if some of the files will be overwritten
157         List<FileSystemObject> curFiles = onSelectionListener.onRequestCurrentItems();
158         if (curFiles != null) {
159             // Is necessary to ask the user?
160             if (isOverwriteNeeded(files, curFiles)) {
161                 //Show a dialog asking the user for overwrite the files
162                 AlertDialog dialog =
163                         DialogHelper.createTwoButtonsQuestionDialog(
164                                 ctx,
165                                 android.R.string.cancel,
166                                 R.string.overwrite,
167                                 R.string.confirm_overwrite,
168                                 ctx.getString(R.string.msgs_overwrite_files),
169                                 new DialogInterface.OnClickListener() {
170                                     @Override
171                                     public void onClick(DialogInterface alertDialog, int which) {
172                                         // NEGATIVE (overwrite) POSITIVE (cancel)
173                                         if (which == DialogInterface.BUTTON_POSITIVE) {
174                                             // Execute background task
175                                             task.execute(task);
176                                         } else if (which == DialogInterface.BUTTON_NEGATIVE) {
177                                             Message msg = new Message();
178                                             msg.what = NavigationActivity.COPYORCUTCANCELFLAG;
179                                             //modify for bug20160714 start
180                                             if (ctx instanceof NavigationActivity) {
181                                                 ((NavigationActivity)ctx).refreshAndTost.sendMessage(msg);
182                                             }
183                                             //modify for bug20160714 end
184                                         }
185                                     }
186                                 });
187                 DialogHelper.delegateDialogShow(ctx, dialog);
188                 return;
189             }
190         }
191 
192         // Execute background task
193         task.execute(task);
194     }

 

4>、move
 1 public static boolean move(final Context context, final String src, final String dst, Console console)
 2             throws FileNotFoundException, IOException, ConsoleAllocException,
 3             NoSuchFileOrDirectory, InsufficientPermissionsException,
 4             CommandNotFoundException, OperationTimeoutException,
 5             ExecutionException, InvalidCommandDefinitionException, ReadOnlyFilesystemException,
 6             CancelledOperationException {
 7         Console cSrc = ensureConsoleForFile(context, console, src);
 8         Console cDst = ensureConsoleForFile(context, console, dst);
 9         boolean ret = true;
10         if (cSrc.equals(cDst)) {
11             // Is safe to use the same console
12             MoveExecutable executable =
13                     cSrc.getExecutableFactory().newCreator().createMoveExecutable(src, dst);
14             writableExecute(context, executable, cSrc);
15             ret = executable.getResult().booleanValue();
16             //added by huangyang 2015.12.16 for JIra [Angus3-e7 ANGUSIIIE-777]
17             if(ret) {}
18             //end
19         } else {}
20 
21         // Do media scan (don't scan the file if is virtual file)
22         if (ret) {
23             File parent = new File(dst).getParentFile();
24             if (parent != null && !VirtualMountPointConsole.isVirtualStorageResource(parent
25                     .getAbsolutePath())) {
26 
27                 //modified by huangyang 2015.12.21 for Jira Angus3-a4 16GB ANGUSIIIGP-11
28                 if("AUDIO".equals(MimeTypeHelper.getCategory(context, new File(src)).toString()) ||
29                         "VIDEO".equals(MimeTypeHelper.getCategory(context, new File(src)).toString())) {
30                     Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
31                     ContentResolver resolver = context.getContentResolver();
32                     Cursor cursor = resolver.query(uri, new String[] {MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media._ID}, 
33                             MediaStore.Audio.Media.DATA + "='"+ src + "'", null, null);
34                     String album = null;
35                     int id = 0;
36                     if (cursor != null) {
37                         if(cursor.getCount() > 0){
38                             cursor.moveToFirst();
39                             album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
40                             id = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media._ID));
41                         }
42                         cursor.close();
43                     }
44 
45                     if(album !=null ){
46                         if(album.equals("FM recordings") || album.equals("CallRecord") || album.equals("Audio recordings")) {
47                             if(id > 0) {
48                                 ContentValues values = new ContentValues();
49                                 values.put(MediaStore.Audio.Media.DATA, dst);
50                                 String newTitle = dst.substring(0, dst.lastIndexOf("."));
51                                 if(newTitle.lastIndexOf(File.separator) > -1) {
52                                     newTitle = newTitle.substring(newTitle.lastIndexOf(File.separator)+1);
53                                 }
54                                 values.put(MediaStore.Audio.Media.DISPLAY_NAME, newTitle);
55                                 values.put(MediaStore.Audio.Media.TITLE, newTitle);//add by fengertong ANGUSIIIE-1230
56                                 resolver.update(uri, values, MediaStore.Audio.Media._ID + "=?", 
57                                         new String[]{String.valueOf(id)});
58                             }
59                         } else {
60                             // Remove from mediascanner
61                             MediaScannerConnection.scanFile(context, new String[]{
62                                     MediaHelper.normalizeMediaPath(src),
63                                     MediaHelper.normalizeMediaPath(dst)
64                             }, null, new OnScanCompletedListener() {
65 
66                                 @Override
67                                 public void onScanCompleted(String path, Uri uri) {
68 
69                                     ContentValues values = new ContentValues();
70                                     String newTitle = dst.substring(0, dst.lastIndexOf("."));
71                                     if(newTitle.lastIndexOf(File.separator) > -1) {
72                                         newTitle = newTitle.substring(newTitle.lastIndexOf(File.separator)+1);
73                                     }
74                                     values.put(MediaStore.Audio.Media.TITLE, newTitle);
75                                     context.getContentResolver().update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values, 
76                                             MediaStore.Audio.Media.DATA + "=?", new String[]{dst});
77                                 }
78                             });
79                         }
80                     }
81                 } else {
82                     // Remove from mediascanner
83                     MediaScannerConnection.scanFile(context, new String[]{
84                             MediaHelper.normalizeMediaPath(src),
85                             MediaHelper.normalizeMediaPath(dst)
86                     }, null, null);
87                 }
88                 //end
89             }
90         }
91 
92         return ret;
93     }

 

5>、createMoveExecutable
 1 MoveExecutable createMoveExecutable(String src, String dst) throws CommandNotFoundException,
 2     NoSuchFileOrDirectory, InsufficientPermissionsException;
 3     MoveCommand.java
 4 
 5     @Override
 6     public void execute()
 7             throws InsufficientPermissionsException, NoSuchFileOrDirectory, ExecutionException,
 8             CancelledOperationException {
 9         if (isTrace()) {
10             Log.v(TAG,
11                     String.format("Creating from %s to %s", this.mSrc, this.mDst)); //$NON-NLS-1$
12         }
13 
14         File s = new File(this.mSrc);
15         File d = new File(this.mDst);
16         if (!s.exists()) {
17             if (isTrace()) {
18                 Log.v(TAG, "Result: FAIL. NoSuchFileOrDirectory"); //$NON-NLS-1$
19             }
20             throw new NoSuchFileOrDirectory(this.mSrc);
21         }
22 
23         //Move or copy recursively
24         if (d.exists()) {
25             if (!FileHelper.copyRecursive(s, d, getBufferSize(), this)) {
26                 if (isTrace()) {
27                     Log.v(TAG, "Result: FAIL. InsufficientPermissionsException"); //$NON-NLS-1$
28                 }
29                 throw new InsufficientPermissionsException();
30             }
31             if (!FileHelper.deleteFolder(s)) {
32                 if (isTrace()) {
33                     Log.v(TAG, "Result: OK. WARNING. Source not deleted."); //$NON-NLS-1$
34                 }
35             }
36         } else {
37             // Move between filesystem is not allow. If rename fails then use copy operation
38             if (!s.renameTo(d)) {
39                 if (!FileHelper.copyRecursive(s, d, getBufferSize(), this)) {
40                     if (isTrace()) {
41                         Log.v(TAG, "Result: FAIL. InsufficientPermissionsException"); //$NON-NLS-1$
42                     }
43                     throw new InsufficientPermissionsException();
44                 }
45                 if (!FileHelper.deleteFolder(s)) {
46                     if (isTrace()) {
47                         Log.v(TAG, "Result: OK. WARNING. Source not deleted."); //$NON-NLS-1$
48                     }
49                 }
50             }
51         }
52 
53         if (isTrace()) {
54             Log.v(TAG, "Result: OK"); //$NON-NLS-1$
55         }
56     }

 

6>、copyRecursive
 1 /**
 2      * Method that copies recursively to the destination
 3      *
 4      * @param src The source file or folder
 5      * @param dst The destination file or folder
 6      * @param bufferSize The buffer size for the operation
 7      * @return boolean If the operation complete successfully
 8      * @throws ExecutionException If a problem was detected in the operation
 9      */
10     public static boolean copyRecursive(
11             final File src, final File dst, int bufferSize, Program program)
12                     throws ExecutionException, CancelledOperationException {
13         if (src.isDirectory()) {
14             // Create the directory
15             if (dst.exists() && !dst.isDirectory()) {
16                 Log.e(TAG,
17                         String.format("Failed to check destionation dir: %s", dst)); //$NON-NLS-1$
18                 throw new ExecutionException("the path exists but is not a folder"); //$NON-NLS-1$
19             }
20             boolean result = false;
21             if (!dst.exists()) {
22                 result = dst.mkdir();
23                 if (!result) {
24                     Log.e(TAG, String.format("Failed to create directory: %s", dst)); //$NON-NLS-1$
25                     return false;
26                 }
27             }
28             File[] files = src.listFiles();
29             if (files != null) {
30                 int len = files.length;
31 
32                 /*modify by z start*/    
33                 /*if (result) {
34     len -= 1;
35     }*/
36                 /*modify by z end*/
37 
38                 for (int i = 0; i < len; i++) {
39                     // Short circuit if we've been cancelled. Show's over :(
40                     if (program.isCancelled()) {
41                         throw new CancelledOperationException();
42                     }
43 
44                     if (!copyRecursive(files[i], new File(dst, files[i].getName()), bufferSize,
45                             program)) {
46                         return false;
47                     }
48                 }
49             }
50         } else {
51             // Copy the directory
52             if (!bufferedCopy(src, dst,bufferSize, program)) {
53                 return false;
54             }
55         }
56         return true;
57     }

 

7>、bufferedCopy
 1 /**
 2      * Method that copies a file
 3      *
 4      * @param src The source file
 5      * @param dst The destination file
 6      * @param bufferSize The buffer size for the operation
 7      * @return boolean If the operation complete successfully
 8      */
 9     public static boolean bufferedCopy(final File src, final File dst,
10             int bufferSize, Program program)
11                     throws ExecutionException, CancelledOperationException {
12         BufferedInputStream bis = null;
13         BufferedOutputStream bos = null;
14         try {
15             bis = new BufferedInputStream(new FileInputStream(src), bufferSize);
16             bos = new BufferedOutputStream(new FileOutputStream(dst), bufferSize);
17             int read = 0;
18             byte[] data = new byte[bufferSize];
19             while ((read = bis.read(data, 0, bufferSize)) != -1) {
20                 // Short circuit if we've been cancelled. Show's over :(
21                 if (program.isCancelled()) {
22                     throw new CancelledOperationException();
23                 }
24                 bos.write(data, 0, read);  //看到了吧,最终的文件拷贝,黏贴就是io流的操作
25             }
26             return true;
27 
28         } catch (Throwable e) {} finally {}
29     }

 

转载于:https://www.cnblogs.com/wangqx/p/6076522.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值