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

来源:互联网 发布:伍聚网络 编辑:程序博客网 时间:2024/06/15 18:24

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

效果如下:



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


主要知识点如下:

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<String, Integer, String> ... ...

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<String, Integer, String> {        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


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:padding="@dimen/activity_horizontal_margin"    android:orientation="vertical">    <ProgressBar        android:id="@+id/progressBar"        style="@style/MyProgressBar2"        android:layout_width="match_parent"        android:layout_height="50dp"        android:layout_gravity="center_horizontal"        android:progress="30" />    <TextView        android:id="@+id/textViewMessage"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Small Text"        android:textAppearance="?android:attr/textAppearanceSmall" /></LinearLayout>


activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity">    <TextView        android:id="@+id/txt"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center_horizontal"        android:text="file copy & move example" />    <Button        android:id="@+id/btnClearAll"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="1.CLEAR ALL" />    <Button        android:id="@+id/btnCreateOnPhone"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="2.create SOME FILES on PHONE" />    <Button        android:id="@+id/btnPhonetoSDCard"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="3.COPY TO ex SDCARD" />    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/txtInfo"        /></LinearLayout>


progress_horizontal.xml
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">    <item android:id="@android:id/background">        <shape android:thickness="1dp">            <!--<solid android:color="@color/button_green_border_color" />-->            <corners android:radius="1dip" />            <solid android:color="@color/TintGrey" >            </solid>        </shape>    </item>    <item android:id="@android:id/secondaryProgress">        <clip>            <shape>                <corners android:radius="1dip" />                <solid android:color="@color/button_green_color" />            </shape>        </clip>    </item>    <item android:id="@android:id/progress">        <clip>            <shape>                <corners android:radius="1dip" />                <solid android:color="@color/button_green_color" />            </shape>        </clip>    </item></layer-list>

styles.xml

<resources>    <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->    </style>    <style name="MyProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal">    </style>    <style name="MyProgressBar2" parent="android:Widget.ProgressBar.Horizontal">        <item name="android:progressDrawable">@drawable/progress_horizontal</item>    </style></resources>

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

或者:源代码戳这里




1 0
原创粉丝点击