Android之zip文件加密解压及进度条的实现
16lz
2021-01-24
zip文件的解压能够使用java的zip库,可是没有实现对加密文件的解压功能,这里能够使用zip4j来实现。详细能够參看该文《Android下zip压缩文件加密解密的完美解决方式》。该文件里没有实现解压进度的功能,这里进行一简单的实现。
Zip4jSp.java
/** * unzip file to dest dir with password in thread. * * @param zipFile * @param dest * @param passwd * @param charset * null or empty is utf-8 * @param Handler * handler in thread * @param isDeleteZipFile * true:delete zip file.false:not. * @throws ZipException */public static void Unzip(final File zipFile, String dest, String passwd,String charset, final Handler handler, final boolean isDeleteZipFile)throws ZipException {ZipFile zFile = new ZipFile(zipFile);if (TextUtils.isEmpty(charset)) {charset = "UTF-8";}zFile.setFileNameCharset(charset);if (!zFile.isValidZipFile()) {throw new ZipException("Compressed files are not illegal, may be damaged.");}File destDir = new File(dest); // Unzip directoryif (destDir.isDirectory() && !destDir.exists()) {destDir.mkdir();}if (zFile.isEncrypted()) {zFile.setPassword(passwd.toCharArray());}final ProgressMonitor progressMonitor = zFile.getProgressMonitor();Thread progressThread = new Thread(new Runnable() {@Overridepublic void run() {Bundle bundle = null;Message msg = null;try {int percentDone = 0;// long workCompleted=0;// handler.sendEmptyMessage(ProgressMonitor.RESULT_SUCCESS)if (handler == null) {return;}handler.sendEmptyMessage(CompressStatus.START);while (true) {Thread.sleep(1000);percentDone = progressMonitor.getPercentDone();bundle = new Bundle();bundle.putInt(CompressKeys.PERCENT, percentDone);msg = new Message();msg.what = CompressStatus.HANDLING;msg.setData(bundle);handler.sendMessage(msg);if (percentDone >= 100) {break;}}handler.sendEmptyMessage(CompressStatus.COMPLETED);} catch (InterruptedException e) {bundle = new Bundle();bundle.putString(CompressKeys.ERROR, e.getMessage());msg = new Message();msg.what = CompressStatus.ERROR;msg.setData(bundle);handler.sendMessage(msg);e.printStackTrace();}finally{if(isDeleteZipFile){zipFile.deleteOnExit();//zipFile.delete();}}}});progressThread.start();zFile.setRunInThread(true);zFile.extractAll(dest);}
注:
(1)、字符集默认採用UTF-8
(2)、解压文件在线程中进行,所以须要setRunInThread(true).因为採用线程中解压文件,所以调用该函数时相当于异步运行,调用代码会直接往下走,须要注意并加以处理。
(3)、进度条另开了一个线程来处理,并将处理的结果以handler的形式发送
(4)、使用zipFile.deleteOnExit()而不是zipFile.delete();由于使用线程解压时,尽管从progressMonitor获得的percentDone已经达到了100,而其实数据并没有全然解压完毕。这时退出循环执行finally的delete函数,假设使用zipFile.delete(),将会删除文件,这样会使兴许的解压失败。而使用zipFile.deleteOnExit()函数,该函数是当VM终止时才会删除文件,与zipFile.delete()删除文件不同。APP在执行时,VM始终是在的,所以这样删除可以确保兴许的解压可以正常进行。或者不去删除文件。
(5)、handler的代码见后文的MainActivity.java。
package com.sparkle.compress;public class CompressKeys {public final static String PERCENT="PERCENT";public final static String ERROR="ERROR";}
CompressStatus.java
package com.sparkle.compress;public class CompressStatus {public final static int START=0;public final static int HANDLING=1;public final static int COMPLETED=2;public final static int ERROR=3;}
private Handler _handler=new Handler(){@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case CompressStatus.START:{setTitle("Start...");break;}case CompressStatus.HANDLING:{Bundle bundle=msg.getData();int percent=bundle.getInt(CompressKeys.PERCENT);setTitle(percent+"%");break;}case CompressStatus.ERROR:{Bundle bundle=msg.getData();String error=bundle.getString(CompressKeys.ERROR);_info_textView.setText(error);break;}case CompressStatus.COMPLETED:{setTitle("Completed");byte[] data=FileSp.read(tempFilePath);try {String dataStr=new String(data,"UTF-8");_info_textView.setText(dataStr);} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}break;}default:break;}};};}
以下是效果图
更多相关文章
- C语言函数的递归(上)
- Android(安卓)studio 使用心得(四)---android studio 多渠道打包
- 1、android orm之greendao
- Android读取工程根目录下文件内容
- 【Android】Handler 关于 new Handler 的问题
- android如何停止Thread和AsyncTask
- android 杂
- Android(安卓)中自定义控件和属性(attr.xml,declare-styleable,T
- Android中onMesure研究(2)