Android 下载Zip文件并解压,获取文件中图片展示

picture.jpg

实现步骤

1.下载文件

文件的下载我使用了# FileDownloader这个库,FileDownloader功能十分强大,我这里只是简单地用了一下。
配置好下载地址和文件保存路径就行,啥都不用管。

    BaseDownloadTask singleTask;
    public int singleTaskId = 0;
    //文件下载地址
    private String downloadUrl = "https://b2c-store.oss-ap-southeast-1.aliyuncs.com/ceshi/FRT.zip";
    //文件保存路径
    private String saveZipFilePath = FileDownloadUtils.getDefaultSaveRootPath() + File.separator + "horizon"
            + File.separator + "MyFolder";
    //下载下来的文件名称
    private String fileName;

    private void startDownload() {
        singleTask = FileDownloader.getImpl().create(downloadUrl)
                .setPath(saveZipFilePath, true)
                .setCallbackProgressTimes(300)
                .setMinIntervalUpdateSpeed(400)
                .setListener(new FileDownloadSampleListener() {
                    @Override
                    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                        super.pending(task, soFarBytes, totalBytes);
                    }

                    @Override
                    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                        Log.e(TAG, "----->progress taskId:" + task.getId() + ",soFarBytes:" + soFarBytes + ",totalBytes:" + totalBytes
                                + ",percent:" + soFarBytes * 1.0 / totalBytes + ",speed:" + task.getSpeed());
                        super.progress(task, soFarBytes, totalBytes);
                    }

                    @Override
                    protected void blockComplete(BaseDownloadTask task) {
                        Log.e(TAG,"----------->blockComplete taskId:" + task.getId() + ",filePath:" + task.getPath() +
                                ",fileName:" + task.getFilename() + ",speed:" + task.getSpeed() + ",isReuse:" + task.reuse());
                        fileName = task.getFilename();
                        super.blockComplete(task);
                    }

                    @Override
                    protected void completed(BaseDownloadTask task) {
                        Log.e(TAG,"---------->completed taskId:" + task.getId() + ",isReuse:" + task.reuse());
                        super.completed(task);
                    }

                    @Override
                    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                        super.paused(task, soFarBytes, totalBytes);
                    }

                    @Override
                    protected void error(BaseDownloadTask task, Throwable e) {
                        Log.e(TAG, "--------->error taskId:" + task.getId() + ",e:" + e.getLocalizedMessage());
                        super.error(task, e);
                    }

                    @Override
                    protected void warn(BaseDownloadTask task) {
                        super.warn(task);
                    }
                });
        singleTaskId = singleTask.start();
    }

}

2.解压文件

我这里解压的是zip文件,懒得找第三方库了,直接使用Java提供的ZipFile。把文件解压出来用输入输出流保存就行。

 /**
     * zipFile 压缩文件
     * folderPath 解压后的文件路径
     * */
    private void unZipFile(File zipFile, String folderPath) {
        try {
            ZipFile zfile = new ZipFile(zipFile);
            Enumeration zList = zfile.entries();
            ZipEntry ze = null;
            byte[] buf = new byte[1024];
            while (zList.hasMoreElements()) {
                ze = (ZipEntry) zList.nextElement();

                if (ze.isDirectory()) {
                    String dirstr = folderPath +  File.separator + ze.getName();
                    dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
                    File f = new File(dirstr);
                    boolean mdir = f.mkdir();
                    continue;
                }

                OutputStream os = new BufferedOutputStream(new FileOutputStream(getRealFileName(folderPath,ze.getName())));
                Log.e(TAG,"---->getRealFileName(folderPath,ze.getName()): " + getRealFileName(folderPath,ze.getName()).getPath() + "  name:" + getRealFileName(folderPath,ze.getName()).getName());
                InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
                int readLen = 0;
                while ((readLen = is.read(buf, 0, 1024)) != -1) {
                    os.write(buf, 0, readLen);
                }
                is.close();
                os.close();
            }
            zfile.close();

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

        //解压完成之后删除压缩包
        deleteDir(zipFile);
    }

用到了两个方法,一个是getRealFileName,用于生成实际的文件来保存解压后的文件。一个是deleteDir,用于删除压缩文件。

 /**
     * 根据保存zip的文件路径和zip文件相对路径名,返回一个实际的文件
     * 因为zip文件解压后,里边可能是多重文件结构
     * */
    public File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir);
        String substr = null;
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                try {
                    substr = new String(substr.getBytes("8859_1"), "GB2312");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                ret = new File(ret, substr);

            }
            if (!ret.exists()) {
                ret.mkdirs();
            }
            substr = dirs[dirs.length - 1];
            try {
                substr = new String(substr.getBytes("8859_1"), "GB2312");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            ret = new File(ret, substr);
            return ret;
        }
        return ret;
    }
 /**
     * 删除整个文件夹 或者 文件
     */
    public void deleteDir(File file) {
        if (!file.exists()) {
            return;
        }
        if (file.isDirectory()) {
            File[] childFiles = file.listFiles();
            if (childFiles == null || childFiles.length == 0) {
                file.delete();
            }

            for (int index = 0; index < childFiles.length; index++) {
                deleteDir(childFiles[index]);
            }
        }
        file.delete();
    }


3.最后是从解压后的文件中找出图片文件来进行展示

 /**
     * 存放当前文件夹下所有图片文件的路径的集合
     * **/
    private ArrayList<String> paths = new ArrayList<String>();

    /**
     * 从解压后的文件中获取图片进行展示
     * */
    private void getAndShowPicture() {
        paths.clear();

        Map<String,Bitmap> maps = new TreeMap<String, Bitmap>();
        try {
            maps = getImages(saveZipFilePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


        //将获取到的图片放在ImageView中用Viewpager展示
        final List<ImageView> images = new ArrayList<>();
        for (Map.Entry<String,Bitmap> entry : maps.entrySet()) {
            if(null == entry.getValue()){
                continue;
            }
            ImageView iv = new ImageView(this);
            iv.setImageBitmap(entry.getValue());
            images.add(iv);
        }

        vp_picture.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return images.size();
            }

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                //添加页卡
                container.addView(images.get(position), 0);
                return images.get(position);
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView(images.get(position));
            }
        });

    }

    /**
     * 获取指定文件夹下面的所有图片的文件目录和其Bitmap对象
     */
    private Map<String, Bitmap> getImages(String filePath) throws FileNotFoundException {
        File baseFile = new File(filePath);

        Map<String, Bitmap> maps = new TreeMap<String, Bitmap>();
        if (baseFile != null && baseFile.exists()) {
            getFiles(paths,baseFile);
            if (!paths.isEmpty()) {
                for (int i = 0; i < paths.size(); i++) {
                    Bitmap bitmap = BitmapFactory.decodeFile(paths.get(i));
                    maps.put(paths.get(i), bitmap);
                }
            }
        }
        return maps;
    }


    /**
     * 获取图片路径
     * */
    private  void getFiles(List list, File file){
        File[] fs = file.listFiles();
        for(File f:fs){
            if(f.isDirectory()) {
                getFiles(list,f);
            }
            if(f.isFile()) {
                Log.e(TAG,"------------->getFiles  f:" + f.getAbsolutePath() );
                if(isImageFile(f.getAbsolutePath())){
                    list.add(f.getAbsolutePath());
                }
            }
        }
    }

    /**
     * 判断文件是否是图片
     * */
    private boolean isImageFile(String filePath){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath,options);
        if(options.outWidth == -1){
            return false;
        }
        return true;
    }


我在做这个功能的时候遇到一个问题。由于手机没有外部存储卡,压缩文件我保存在了应用专属文件目录下(即/storage/emulated/0/Android/data/PackageName/)。手机连接电脑之后,从电脑中打开手机的内部存储,有的手机可以找到这个目录然后把一个压缩文件放进去。我把压缩文件放进去之后在应用里执行解压代码将文件进行解压,结果发现3张图片只解压出来一张(Log显示所有的图片都解压并保存完毕),之后我反复做各种尝试,效果还是一样,直到我的手机不让我再往里边随意放东西。。。。。。
最后我用同样的代码,从服务器上下载下来一个只包含图片的压缩文件进行解压,结果解压和获取解压后的图片文件都顺顺利利的,我也不知道为啥子。

下边附上完整代码

package com.adminstrator.guaguakaapplication;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;

import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadSampleListener;
import com.liulishuo.filedownloader.FileDownloader;
import com.liulishuo.filedownloader.util.FileDownloadUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class LoadAndUnzipFileActivity extends AppCompatActivity {

    private String TAG = getClass().getSimpleName();

    private Button btn_download, btn_unzip, btn_show_picture;
    private ViewPager vp_picture;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_load_and_unzip_file);
        initViews();
    }

    private void initViews() {
        btn_download = findViewById(R.id.btn_download);
        btn_unzip = findViewById(R.id.btn_unzip);
        btn_show_picture = findViewById(R.id.btn_show_picture);
        vp_picture = findViewById(R.id.vp_picture);

        btn_download.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startDownload();
            }
        });

        btn_unzip.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unZipFile(new File(saveZipFilePath + File.separator + fileName),saveZipFilePath);
            }
        });

        btn_show_picture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getAndShowPicture();
            }
        });
    }


    /**
     * 存放当前文件夹下所有图片文件的路径的集合
     * **/
    private ArrayList<String> paths = new ArrayList<String>();

    /**
     * 从解压后的文件中获取图片进行展示
     * */
    private void getAndShowPicture() {
        paths.clear();

        Map<String,Bitmap> maps = new TreeMap<String, Bitmap>();
        try {
            maps = getImages(saveZipFilePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }


        //将获取到的图片放在ImageView中用Viewpager展示
        final List<ImageView> images = new ArrayList<>();
        for (Map.Entry<String,Bitmap> entry : maps.entrySet()) {
            if(null == entry.getValue()){
                continue;
            }
            ImageView iv = new ImageView(this);
            iv.setImageBitmap(entry.getValue());
            images.add(iv);
        }

        vp_picture.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return images.size();
            }

            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                //添加页卡
                container.addView(images.get(position), 0);
                return images.get(position);
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                container.removeView(images.get(position));
            }
        });

    }

    /**
     * 获取指定文件夹下面的所有图片的文件目录和其Bitmap对象
     */
    private Map<String, Bitmap> getImages(String filePath) throws FileNotFoundException {
        File baseFile = new File(filePath);

        Map<String, Bitmap> maps = new TreeMap<String, Bitmap>();
        if (baseFile != null && baseFile.exists()) {
            getFiles(paths,baseFile);
            if (!paths.isEmpty()) {
                for (int i = 0; i < paths.size(); i++) {
                    Bitmap bitmap = BitmapFactory.decodeFile(paths.get(i));
                    maps.put(paths.get(i), bitmap);
                }
            }
        }
        return maps;
    }


    /**
     * 获取图片路径
     * */
    private  void getFiles(List list, File file){
        File[] fs = file.listFiles();
        for(File f:fs){
            if(f.isDirectory()) {
                getFiles(list,f);
            }
            if(f.isFile()) {
                Log.e(TAG,"------------->getFiles  f:" + f.getAbsolutePath() );
                if(isImageFile(f.getAbsolutePath())){
                    list.add(f.getAbsolutePath());
                }
            }
        }
    }

    /**
     * 判断文件是否是图片
     * */
    private boolean isImageFile(String filePath){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath,options);
        if(options.outWidth == -1){
            return false;
        }
        return true;
    }


    /**
     * zipFile 压缩文件
     * folderPath 解压后的文件路径
     * */
    private void unZipFile(File zipFile, String folderPath) {
        try {
            ZipFile zfile = new ZipFile(zipFile);
            Enumeration zList = zfile.entries();
            ZipEntry ze = null;
            byte[] buf = new byte[1024];
            while (zList.hasMoreElements()) {
                ze = (ZipEntry) zList.nextElement();

                if (ze.isDirectory()) {
                    String dirstr = folderPath +  File.separator + ze.getName();
                    dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
                    File f = new File(dirstr);
                    boolean mdir = f.mkdir();
                    continue;
                }

                OutputStream os = new BufferedOutputStream(new FileOutputStream(getRealFileName(folderPath,ze.getName())));
                Log.e(TAG,"---->getRealFileName(folderPath,ze.getName()): " + getRealFileName(folderPath,ze.getName()).getPath() + "  name:" + getRealFileName(folderPath,ze.getName()).getName());
                InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
                int readLen = 0;
                while ((readLen = is.read(buf, 0, 1024)) != -1) {
                    os.write(buf, 0, readLen);
                }
                is.close();
                os.close();
            }
            zfile.close();

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

        //解压完成之后删除压缩包
        deleteDir(zipFile);
    }

    /**
     * 根据保存zip的文件路径和zip文件相对路径名,返回一个实际的文件
     * 因为zip文件解压后,里边可能是多重文件结构
     * */
    public File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir);
        String substr = null;
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                try {
                    substr = new String(substr.getBytes("8859_1"), "GB2312");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                ret = new File(ret, substr);

            }
            if (!ret.exists()) {
                ret.mkdirs();
            }
            substr = dirs[dirs.length - 1];
            try {
                substr = new String(substr.getBytes("8859_1"), "GB2312");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            ret = new File(ret, substr);
            return ret;
        }
        return ret;
    }

    /**
     * 删除整个文件夹 或者 文件
     */
    public void deleteDir(File file) {
        if (!file.exists()) {
            return;
        }
        if (file.isDirectory()) {
            File[] childFiles = file.listFiles();
            if (childFiles == null || childFiles.length == 0) {
                file.delete();
            }

            for (int index = 0; index < childFiles.length; index++) {
                deleteDir(childFiles[index]);
            }
        }
        file.delete();
    }



    BaseDownloadTask singleTask;
    public int singleTaskId = 0;
    //文件下载地址
    private String downloadUrl = "https://b2c-store.oss-ap-southeast-1.aliyuncs.com/ceshi/FRT.zip";
    //文件保存路径
    private String saveZipFilePath = FileDownloadUtils.getDefaultSaveRootPath() + File.separator + "horizon"
            + File.separator + "MyFolder";
    //下载下来的文件名称
    private String fileName;

    private void startDownload() {
        singleTask = FileDownloader.getImpl().create(downloadUrl)
                .setPath(saveZipFilePath, true)
                .setCallbackProgressTimes(300)
                .setMinIntervalUpdateSpeed(400)
                .setListener(new FileDownloadSampleListener() {
                    @Override
                    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                        super.pending(task, soFarBytes, totalBytes);
                    }

                    @Override
                    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                        Log.e(TAG, "----->progress taskId:" + task.getId() + ",soFarBytes:" + soFarBytes + ",totalBytes:" + totalBytes
                                + ",percent:" + soFarBytes * 1.0 / totalBytes + ",speed:" + task.getSpeed());
                        super.progress(task, soFarBytes, totalBytes);
                    }

                    @Override
                    protected void blockComplete(BaseDownloadTask task) {
                        Log.e(TAG,"----------->blockComplete taskId:" + task.getId() + ",filePath:" + task.getPath() +
                                ",fileName:" + task.getFilename() + ",speed:" + task.getSpeed() + ",isReuse:" + task.reuse());
                        fileName = task.getFilename();
                        super.blockComplete(task);
                    }

                    @Override
                    protected void completed(BaseDownloadTask task) {
                        Log.e(TAG,"---------->completed taskId:" + task.getId() + ",isReuse:" + task.reuse());
                        super.completed(task);
                    }

                    @Override
                    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
                        super.paused(task, soFarBytes, totalBytes);
                    }

                    @Override
                    protected void error(BaseDownloadTask task, Throwable e) {
                        Log.e(TAG, "--------->error taskId:" + task.getId() + ",e:" + e.getLocalizedMessage());
                        super.error(task, e);
                    }

                    @Override
                    protected void warn(BaseDownloadTask task) {
                        super.warn(task);
                    }
                });
        singleTaskId = singleTask.start();
    }

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容