安卓异步复制文件对话框的实现,从手机移动整个文件夹到外置存储卡

本例实现了将APP的数据从手机内存移动到外置存储卡。

效果如下:

安卓异步复制文件对话框的实现,从手机移动整个文件夹到外置存储卡_第1张图片


不看文章,接下载源代码戳这里


主要知识点如下:

1、获得APP的数据存储位置:

 

    File[] files = ContextCompat.getExternalFilesDirs(getBaseContext(), null);
File dirPhone = files[0];
File dirSDCard = files[1];

上面的files.length如果=2,那么files[0]是手机内存,files[1]则是外置存储卡。


2、扩展一个使用AsyncTask对象,进行异步复制操作,并提供进度显示。

 public class CopyTask extends AsyncTask 
... ...

3、增加一个DialogFragment,作为弹出来的复制进度框(当然也可以使用DialogProgress,我这里使用DialogFragment的好处是自定义程度较高)。

 @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.copydialog_fragment, container, false);

        progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
        textViewMessage = (TextView) v.findViewById(R.id.textViewMessage);

        CopyTask copyTask = new CopyTask();
        copyTask.dirSourceString = getArguments().getString(CopyDialogFragment.SOURCE_FOLDER);
        copyTask.dirTargetString = getArguments().getString(CopyDialogFragment.TARGET_FOLDER);

        copyTask.execute();

        getDialog().setTitle("copying...");
        return v;
    }

4、主要几个递归复制的方法:

   private  void copyFileOrDirectory(String srcDir, String dstDir) {

            try {
                File src = new File(srcDir);
                File dst = new File(dstDir, src.getName());

                if (src.isDirectory()) {

                    String files[] = src.list();
                    int filesLength = files.length;
                    for (int i = 0; i < filesLength; i++) {
                        String src1 = (new File(src, files[i]).getPath());
                        String dst1 = dst.getPath();
                        copyFileOrDirectory(src1, dst1);

                    }
                } else {
                    copyFile(src, dst);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void copyFile(File sourceFile, File destFile) throws IOException {
            if (!destFile.getParentFile().exists())
                destFile.getParentFile().mkdirs();

            if (!destFile.exists()) {
                destFile.createNewFile();
            }

            FileChannel source = null;
            FileChannel destination = null;

            try {
                source = new FileInputStream(sourceFile).getChannel();
                destination = new FileOutputStream(destFile).getChannel();
                destination.transferFrom(source, 0, source.size());
                progress += source.size();
                updateProgress(progress);
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (source != null) {
                    source.close();
                }
                if (destination != null) {
                    destination.close();
                }
            }
        }

好了,下面是详细内容:

CopyDialogFragment.java

package com.example.terry.storagesample;

import android.app.DialogFragment;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class CopyDialogFragment extends DialogFragment {
    public final static String SOURCE_FOLDER = "SourceFolder";
    public final static String TARGET_FOLDER = "TargetFolder";

    ProgressBar progressBar;
    TextView textViewMessage;

    public ProgressDialogFragmentListener progressDialogFragmentListener;

    @Override
    public void onResume() {
        ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes();
        params.width = ViewGroup.LayoutParams.MATCH_PARENT;
        params.height = 500;
        getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);

        super.onResume();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.copydialog_fragment, container, false);

        progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
        textViewMessage = (TextView) v.findViewById(R.id.textViewMessage);

        CopyTask copyTask = new CopyTask();
        copyTask.dirSourceString = getArguments().getString(CopyDialogFragment.SOURCE_FOLDER);
        copyTask.dirTargetString = getArguments().getString(CopyDialogFragment.TARGET_FOLDER);

        copyTask.execute();

        getDialog().setTitle("copying...");
        return v;
    }


    public static CopyDialogFragment newInstance() {
        return new CopyDialogFragment();
    }

    private void updateProgress(int progress) {
        progressBar.setProgress(progress);
        textViewMessage.setText(String.format("%s/%s", StorageUtil.FormatFileSize(progress), StorageUtil.FormatFileSize(progressBar.getMax())));
    }

    private void SetMax(int max) {
        progressBar.setMax(max);
    }

    private void Finish() {
        if (progressDialogFragmentListener != null) {
            progressDialogFragmentListener.onDialogClosed();
        }
        this.getDialog().dismiss();
    }

    public interface ProgressDialogFragmentListener {
        void onDialogClosed();
    }

    public class CopyTask extends AsyncTask {

        public String dirSourceString;
        public String dirTargetString;

        private int progress;

        @Override
        protected String doInBackground(String... params) {
            progress = 0;
            File src = new File(dirSourceString);
            long size = StorageUtil.dirSize(src);
            SetMax((int) size);
            copyFileOrDirectory(dirSourceString, dirTargetString);
            return null;
        }

        @Override
        protected void onPostExecute(String fileName) {
            super.onPostExecute(fileName);
            Finish();
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            updateProgress(values[0]);
        }

        private  void copyFileOrDirectory(String srcDir, String dstDir) {

            try {
                File src = new File(srcDir);
                File dst = new File(dstDir, src.getName());

                if (src.isDirectory()) {

                    String files[] = src.list();
                    int filesLength = files.length;
                    for (int i = 0; i < filesLength; i++) {
                        String src1 = (new File(src, files[i]).getPath());
                        String dst1 = dst.getPath();
                        copyFileOrDirectory(src1, dst1);

                    }
                } else {
                    copyFile(src, dst);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void copyFile(File sourceFile, File destFile) throws IOException {
            if (!destFile.getParentFile().exists())
                destFile.getParentFile().mkdirs();

            if (!destFile.exists()) {
                destFile.createNewFile();
            }

            FileChannel source = null;
            FileChannel destination = null;

            try {
                source = new FileInputStream(sourceFile).getChannel();
                destination = new FileOutputStream(destFile).getChannel();
                destination.transferFrom(source, 0, source.size());
                progress += source.size();
                updateProgress(progress);
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (source != null) {
                    source.close();
                }
                if (destination != null) {
                    destination.close();
                }
            }
        }


    }
}

MainActivity.java

package com.example.terry.storagesample;

import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class MainActivity extends AppCompatActivity implements CopyDialogFragment.ProgressDialogFragmentListener {

    Button btnClearAll;
    Button btnCreateOnPhone;
    Button btnPhonetoCard;
    TextView txtInfo;

    File dirPhone;
    File dirSDCard;

    final String dirRootName = "JetRoot";


    //获得各存储位置的总共容量和可用容量(SD0、SD1)
    //移动一个文件(SD0 <--> SD1)
    //移动一个目录(SD0 <--> SD1)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnCreateOnPhone = (Button) findViewById(R.id.btnCreateOnPhone);
        btnPhonetoCard = (Button) findViewById(R.id.btnPhonetoSDCard);
        btnClearAll = (Button) findViewById(R.id.btnClearAll);
        txtInfo = (TextView) findViewById(R.id.txtInfo);

        File[] files = ContextCompat.getExternalFilesDirs(getBaseContext(), null);
        dirPhone = files[0];
        dirSDCard = files[1];

        btnClearAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ClearAll();
            }
        });
        btnCreateOnPhone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                CreateDummyFiles(dirPhone);
            }
        });
        btnPhonetoCard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                PhoneToCard();
            }
        });
    }

    private void ClearAll() {
        File filePhoneRoot = new File(dirPhone, dirRootName);
        File fileCardRoot = new File(dirSDCard, dirRootName);
        StorageUtil.DeleteRecursive(filePhoneRoot);
        StorageUtil.DeleteRecursive(fileCardRoot);
        txtInfo.setText("all clear!!");
    }

    private void CreateDummyFiles(File dir) {
        //ROOT
        File dirRoot = new File(dir, dirRootName);
        if (!dirRoot.exists()) dirRoot.mkdir();

        //LEVEL 1
        File dirJetmaster5 = new File(dirRoot, "Jetmaster5");
        File dirDatabaseBackup = new File(dirRoot, "DatabaseBackup");
        if (!dirJetmaster5.exists()) dirJetmaster5.mkdir();
        if (!dirDatabaseBackup.exists()) dirDatabaseBackup.mkdir();

        //LEVEL 2
        File dirJetMaster5_WebSite = new File(dirJetmaster5, "WebSite");
        File dirJetMaster5_DBTools = new File(dirJetmaster5, "DBTools");
        File dirJetMaster5_Database = new File(dirJetmaster5, "Database");
        File dirJetMaster5_JetFiles = new File(dirJetmaster5, "JetFiles");
        if (!dirJetMaster5_WebSite.exists()) dirJetMaster5_WebSite.mkdir();
        if (!dirJetMaster5_DBTools.exists()) dirJetMaster5_DBTools.mkdir();
        if (!dirJetMaster5_Database.exists()) dirJetMaster5_Database.mkdir();
        if (!dirJetMaster5_JetFiles.exists()) dirJetMaster5_JetFiles.mkdir();

        //LEVEL 3
        File dirJetMaster5_JetFiles_JetUpload1 = new File(dirJetMaster5_JetFiles, "JetUpload1");
        File dirJetMaster5_JetFiles_JetBook = new File(dirJetMaster5_JetFiles, "JetBook");
        File dirJetMaster5_JetFiles_JetEmployee = new File(dirJetMaster5_JetFiles, "JetEmployee");

        if (!dirJetMaster5_JetFiles_JetUpload1.exists()) dirJetMaster5_JetFiles_JetUpload1.mkdir();
        if (!dirJetMaster5_JetFiles_JetBook.exists()) dirJetMaster5_JetFiles_JetBook.mkdir();
        if (!dirJetMaster5_JetFiles_JetEmployee.exists())
            dirJetMaster5_JetFiles_JetEmployee.mkdir();


        WriteToPath(dirDatabaseBackup, "JetCommon_D.bak", R.raw.web);
        WriteToPath(dirJetMaster5_WebSite, "Web.config", R.raw.web);
        WriteToPath(dirJetMaster5_DBTools, "Script.config", R.raw.web);
        WriteToPath(dirJetMaster5_Database, "JetCommon_D.mdf", R.raw.web);

        WriteToPath(dirJetMaster5_JetFiles_JetUpload1, "team.mov", R.raw.web);
        WriteToPath(dirJetMaster5_JetFiles_JetBook, "teambook.png", R.raw.abc);
        WriteToPath(dirJetMaster5_JetFiles_JetEmployee, "JetEmployeePhoto.png", R.raw.bcd);

        for (int i = 0; i < 200; i++) {
            String fileNamePhoto = String.format("JetEmployeePhoto_%s.png", i);
            WriteToPath(dirJetMaster5_JetFiles_JetEmployee, fileNamePhoto, R.raw.bcd);
        }

        txtInfo.setText("create finish...");
    }

    private void PhoneToCard() {

        File filePhoneRoot = new File(dirPhone, dirRootName);
        File fileCardRoot = new File(dirSDCard, dirRootName);

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        CopyDialogFragment cDlg = (CopyDialogFragment) getFragmentManager().findFragmentByTag("dialog");
        if (cDlg != null) {
            ft.remove(cDlg);
        }
        ft.addToBackStack(null);


        Bundle args = new Bundle();
        args.putString(CopyDialogFragment.SOURCE_FOLDER, filePhoneRoot.getAbsolutePath());
        args.putString(CopyDialogFragment.TARGET_FOLDER, fileCardRoot.getAbsolutePath());

        CopyDialogFragment copyDialogFragment = CopyDialogFragment.newInstance();
        copyDialogFragment.setArguments(args);

        copyDialogFragment.progressDialogFragmentListener = this;
        copyDialogFragment.setCancelable(false);
        copyDialogFragment.show(ft, "dialog");

    }

    private void WriteToPath(File targetPath, String sourceFileName, int rawFile) {
        File targetFile = new File(targetPath, sourceFileName);
        try {
            InputStream is = getResources().openRawResource(rawFile);
            OutputStream os = new FileOutputStream(targetFile);
            byte[] data = new byte[is.available()];
            is.read(data);
            os.write(data);
            is.close();
            os.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDialogClosed() {
        txtInfo.setText("copy finish...");
    }

}


StorageUtil.java

package com.example.terry.storagesample;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;

/**
 * Created by terry on 2015/10/29.
 */
public class StorageUtil {
    //转换函数
    public static String FormatFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    public static void DeleteRecursive(File fileOrDirectory) {
        if (fileOrDirectory.isDirectory())
            for (File child : fileOrDirectory.listFiles())
                DeleteRecursive(child);

        fileOrDirectory.delete();
    }

    public static long dirSize(File dir) {

        if (dir.exists()) {
            long result = 0;
            File[] fileList = dir.listFiles();
            for(int i = 0; i < fileList.length; i++) {
                // Recursive call if it's a directory
                if(fileList[i].isDirectory()) {
                    result += dirSize(fileList [i]);
                } else {
                    // Sum the file size in bytes
                    result += fileList[i].length();
                }
            }
            return result; // return the file size
        }
        return 0;
    }
}


copydialog_fragment.xml





    

    


activity_main.xml


    

    


progress_horizontal.xml


    
        
            
            
            
            
        
    
    
        
            
                
                
            
        
    
    
        
            
                
                
            
        
    


styles.xml



    
    


    

    



这样一个一个文件粘贴好麻烦啊,要完整源代码的,可以发信息给我,或者QQ:31798808,

或者:源代码戳这里




你可能感兴趣的:(安卓异步复制文件对话框的实现,从手机移动整个文件夹到外置存储卡)