安卓异步复制文件对话框的实现,从手机移动整个文件夹到外置存储卡
2015-11-05 11:24
801 查看
本例实现了将APP的数据从手机内存移动到外置存储卡。
效果如下:
不看文章,接下载源代码戳这里
主要知识点如下:
1、获得APP的数据存储位置:
上面的files.length如果=2,那么files[0]是手机内存,files[1]则是外置存储卡。
2、扩展一个使用AsyncTask对象,进行异步复制操作,并提供进度显示。
3、增加一个DialogFragment,作为弹出来的复制进度框(当然也可以使用DialogProgress,我这里使用DialogFragment的好处是自定义程度较高)。
4、主要几个递归复制的方法:
好了,下面是详细内容:
CopyDialogFragment.java
MainActivity.java
copydialog_fragment.xml
activity_main.xml
progress_horizontal.xml
styles.xml
这样一个一个文件粘贴好麻烦啊,要完整源代码的,可以发信息给我,或者QQ:31798808,
或者:源代码戳这里
效果如下:
不看文章,接下载源代码戳这里
主要知识点如下:
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,
或者:源代码戳这里
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories