您的位置:首页 > 移动开发 > Android开发

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

2015-11-05 11:24 801 查看
本例实现了将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,

或者:源代码戳这里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android asynctask