Android Utility

How To Zip Files Into Directory Programmatically

Zipping folder is very useful when you large number of files are there to send. If you have ‘n’ number of files to send to server through internet then it is good to put all the files in a directory and zip this directory to a zip file and send this single file. Zipping functionality has been used by many areas other than data exchange. This article will explain how to zip directory programmatically.

Files To Zip

Here in this article i have already added 5 jpg files to zip.

screen_before_zip

Add Read And Write Permission In Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="zipfolder.devdeeds.com.zipfolder">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Activity Layout XML

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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: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="zipfolder.devdeeds.com.zipfolder.MainActivity">

    <TextView
        android:id="@+id/progress_text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textColor="#000"
        android:text="Not Started"
        android:layout_marginBottom="20dp"
        android:layout_centerInParent="true" />

    <Button
        android:id="@+id/btn_zip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/progress_text_view"
        android:layout_centerHorizontal="true"
        android:padding="10dp"
        android:text="Zip Folder" />

</RelativeLayout>

Activity Class With Zip function

import android.os.AsyncTask;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class MainActivity extends AppCompatActivity {

    private static final int BUFFER = 2048;
    private CompressFiles mCompressFiles;
    private ArrayList<String> mFilePathList = new ArrayList<>();
    private TextView mProgressView;

    public static File getOutputZipFile(String fileName) {

        File mediaStorageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "devdeeds");

        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            }
        }

        return new File(mediaStorageDir.getPath() + File.separator + fileName);
    }

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

        mProgressView = (TextView) findViewById(R.id.progress_text_view);
        Button btnZip = (Button) findViewById(R.id.btn_zip);

        //Add Files To Zip
        addFilesToZip();

        btnZip.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                mCompressFiles = new CompressFiles();
                mCompressFiles.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            }
        });
    }

    private void addFilesToZip() {
        mFilePathList.add("/storage/emulated/0/File1.jpg");
        mFilePathList.add("/storage/emulated/0/File2.jpg");
        mFilePathList.add("/storage/emulated/0/File3.jpg");
        mFilePathList.add("/storage/emulated/0/File4.jpg");
        mFilePathList.add("/storage/emulated/0/File5.jpg");
    }

    //Function will get the call from compress function
    public void setCompressProgress(int filesCompressionCompleted) {
        mCompressFiles.publish(filesCompressionCompleted);
    }

    //Zipping function
    public void zip(String zipFilePath) {
        try {
            BufferedInputStream origin;
            FileOutputStream dest = new FileOutputStream(zipFilePath);
            ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));

            byte data[] = new byte[BUFFER];

            for (int i = 0; i < mFilePathList.size(); i++) {

                setCompressProgress(i + 1);

                FileInputStream fi = new FileInputStream(mFilePathList.get(i));
                origin = new BufferedInputStream(fi, BUFFER);
                ZipEntry entry = new ZipEntry(mFilePathList.get(i).substring(mFilePathList.get(i).lastIndexOf("/") + 1));
                out.putNextEntry(entry);
                int count;
                while ((count = origin.read(data, 0, BUFFER)) != -1) {
                    out.write(data, 0, count);
                }
                origin.close();
            }

            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //zip() will be called from this AsyncTask as this is long task.
    private class CompressFiles extends AsyncTask<Void, Integer, Boolean> {

        @Override
        protected void onPreExecute() {

            try {
                mProgressView.setText("0% Completed");
            } catch (Exception ignored) {
            }
        }

        protected Boolean doInBackground(Void... urls) {

            File file = getOutputZipFile("zipped_file.zip");

            String zipFileName;
            if (file != null) {
                zipFileName = file.getAbsolutePath();

                if (mFilePathList.size() > 0) {
                    zip(zipFileName);
                }
            }

            return true;
        }

        public void publish(int filesCompressionCompleted) {
            int totalNumberOfFiles = mFilePathList.size();
            publishProgress((100 * filesCompressionCompleted) / totalNumberOfFiles);
        }

        protected void onProgressUpdate(Integer... progress) {

            try {
                mProgressView.setText(Integer.toString(progress[0]) + "% Completed");
            } catch (Exception ignored) {
                ignored.printStackTrace();
            }
        }

        protected void onPostExecute(Boolean flag) {
            Log.d("COMPRESS_TASK", "COMPLETED");
            mProgressView.setText("100 % Completed");
            Toast.makeText(getApplicationContext(), "Zipping Completed", Toast.LENGTH_SHORT).show();
        }
    }
}

Result In Device Storage

screen_after_zip

About author

Rojer is a programmer by profession, but he likes to research new things and is also interested in writing. Devdeeds is his blog, where he writes all the blog posts related to technology, gadgets, mobile apps, games, and related content.

Leave a Reply

Your email address will not be published. Required fields are marked *