Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将zip文件内容解压缩到sd卡中?_Java_Android - Fatal编程技术网

Java 如何将zip文件内容解压缩到sd卡中?

Java 如何将zip文件内容解压缩到sd卡中?,java,android,Java,Android,我想解压缩我的.obb文件内容,其中包含.zim文件的zip文件,并想将这些文件解压缩到我的sd卡中。我用java helperclass尝试了以下方法,如何做到这一点? 对吗 public class MainActivity extends Activity implements IDownloaderClient { private static final String LOG_TAG = "LVLDownloader"; private ProgressBar m

我想解压缩我的.obb文件内容,其中包含.zim文件的zip文件,并想将这些文件解压缩到我的sd卡中。我用java helperclass尝试了以下方法,如何做到这一点? 对吗

   public class MainActivity extends Activity implements IDownloaderClient {
    private static final String LOG_TAG = "LVLDownloader";
    private ProgressBar mPB;

    private TextView mStatusText;
    private TextView mProgressFraction;
    private TextView mProgressPercent;
    private TextView mAverageSpeed;
    private TextView mTimeRemaining;

    private View mDashboard;
    private View mCellMessage;

    private Button mPauseButton;
    private Button mWiFiSettingsButton;

    private boolean mStatePaused;
    private int mState;

    private IDownloaderService mRemoteService;

    private IStub mDownloaderClientStub;

    private void setState(int newState) {
        if (mState != newState) {
            mState = newState;
            mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState));
        }
    }

    private void setButtonPausedState(boolean paused) {
        mStatePaused = paused;
        int stringResourceID = paused ? R.string.text_button_resume :
                R.string.text_button_pause;
        mPauseButton.setText(stringResourceID);
    }

    /**
     * This is a little helper class that demonstrates simple testing of an
     * Expansion APK file delivered by Market. You may not wish to hard-code
     * things such as file lengths into your executable... and you may wish to
     * turn this code off during application development.
     */
    private static class XAPKFile {
        public final boolean mIsMain;
        public final int mFileVersion;
        public final long mFileSize;

        XAPKFile(boolean isMain, int fileVersion, long fileSize) {
            mIsMain = isMain;
            mFileVersion = fileVersion;
            mFileSize = fileSize;
        }
    }

    /**
     * Here is where you place the data that the validator will use to determine
     * if the file was delivered correctly. This is encoded in the source code
     * so the application can easily determine whether the file has been
     * properly delivered without having to talk to the server. If the
     * application is using LVL for licensing, it may make sense to eliminate
     * these checks and to just rely on the server.
     */
    private static final XAPKFile[] xAPKS = {
            new XAPKFile(
                    true, // true signifies a main file
                    4, // the version of the APK that the file was uploaded
                       // against
                    240000L // the length of the file in bytes
            ),
            new XAPKFile(
                    true, // false signifies a patch file
                    3, // the version of the APK that the patch file was uploaded
                       // against
                    24000L // the length of the patch file in bytes
            )            
    };

    /**
     * Go through each of the APK Expansion files defined in the structure above
     * and determine if the files are present and match the required size. Free
     * applications should definitely consider doing this, as this allows the
     * application to be launched for the first time without having a network
     * connection present. Paid applications that use LVL should probably do at
     * least one LVL check that requires the network to be present, so this is
     * not as necessary.
     * 
     * @return true if they are present.
     */
    boolean expansionFilesDelivered() {
        for (XAPKFile xf : xAPKS) {
            String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion);
            if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false))
                return false;
        }
        return true;
    }

    /**
     * Calculating a moving average for the validation speed so we don't get
     * jumpy calculations for time etc.
     */
    static private final float SMOOTHING_FACTOR = 0.005f;

    /**
     * Used by the async task
     */
    private boolean mCancelValidation;

    /**
     * Go through each of the Expansion APK files and open each as a zip file.
     * Calculate the CRC for each file and return false if any fail to match.
     * 
     * @return true if XAPKZipFile is successful
     */
    void validateXAPKZipFiles() {
        AsyncTask<Object, DownloadProgressInfo, Boolean> validationTask = new AsyncTask<Object, DownloadProgressInfo, Boolean>() {

            @Override
            protected void onPreExecute() {
                mDashboard.setVisibility(View.VISIBLE);
                mCellMessage.setVisibility(View.GONE);
                mStatusText.setText(R.string.text_verifying_download);
                mPauseButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        mCancelValidation = true;
                    }
                });
                mPauseButton.setText(R.string.text_button_cancel_verify);
                super.onPreExecute();
            }

            @Override
            protected Boolean doInBackground(Object... params) {
                for (XAPKFile xf : xAPKS) {
                    String fileName = Helpers.getExpansionAPKFileName(
                            MainActivity.this,
                            xf.mIsMain, xf.mFileVersion);
                    if (!Helpers.doesFileExist(MainActivity.this, fileName,
                            xf.mFileSize, false))
                        return false;
                    fileName = Helpers
                            .generateSaveFileName(MainActivity.this, fileName);
                    ZipResourceFile zrf;
                    byte[] buf = new byte[1024 * 256];
                    try {
                        zrf = new ZipResourceFile(fileName);
                        ZipEntryRO[] entries = zrf.getAllEntries();
                        /**
                         * First calculate the total compressed length
                         */
                        long totalCompressedLength = 0;
                        for (ZipEntryRO entry : entries) {
                            totalCompressedLength += entry.mCompressedLength;
                        }
                        float averageVerifySpeed = 0;
                        long totalBytesRemaining = totalCompressedLength;
                        long timeRemaining;
                        /**
                         * Then calculate a CRC for every file in the Zip file,
                         * comparing it to what is stored in the Zip directory.
                         * Note that for compressed Zip files we must extract
                         * the contents to do this comparison.
                         */
                        for (ZipEntryRO entry : entries) {
                            if (-1 != entry.mCRC32) {
                                long length = entry.mUncompressedLength;
                                CRC32 crc = new CRC32();
                                DataInputStream dis = null;
                                try {
                                    dis = new DataInputStream(
                                            zrf.getInputStream(entry.mFileName));

                                    long startTime = SystemClock.uptimeMillis();
                                    while (length > 0) {
                                        int seek = (int) (length > buf.length ? buf.length
                                                : length);
                                        dis.readFully(buf, 0, seek);
                                        crc.update(buf, 0, seek);
                                        length -= seek;
                                        long currentTime = SystemClock.uptimeMillis();
                                        long timePassed = currentTime - startTime;
                                        if (timePassed > 0) {
                                            float currentSpeedSample = (float) seek
                                                    / (float) timePassed;
                                            if (0 != averageVerifySpeed) {
                                                averageVerifySpeed = SMOOTHING_FACTOR
                                                        * currentSpeedSample
                                                        + (1 - SMOOTHING_FACTOR)
                                                        * averageVerifySpeed;
                                            } else {
                                                averageVerifySpeed = currentSpeedSample;
                                            }
                                            totalBytesRemaining -= seek;
                                            timeRemaining = (long) (totalBytesRemaining / averageVerifySpeed);
                                            this.publishProgress(
                                                    new DownloadProgressInfo(
                                                            totalCompressedLength,
                                                            totalCompressedLength
                                                                    - totalBytesRemaining,
                                                            timeRemaining,
                                                            averageVerifySpeed)
                                                    );
                                        }
                                        startTime = currentTime;
                                        if (mCancelValidation)
                                            return true;
                                    }
                                    if (crc.getValue() != entry.mCRC32) {
                                        Log.e(Constants.TAG,
                                                "CRC does not match for entry: "
                                                        + entry.mFileName);
                                        Log.e(Constants.TAG,
                                                "In file: " + entry.getZipFileName());
                                        return false;
                                    }
                                } finally {
                                    if (null != dis) {
                                        dis.close();
                                    }
                                }
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        return false;
                    }
                }
                return true;
            }

            @Override
            protected void onProgressUpdate(DownloadProgressInfo... values) {
                onDownloadProgress(values[0]);
                super.onProgressUpdate(values);
            }

            @Override
            protected void onPostExecute(Boolean result) {
                if (result) {
                    mDashboard.setVisibility(View.VISIBLE);
                    mCellMessage.setVisibility(View.GONE);
                    mStatusText.setText(R.string.text_validation_complete);
                    mPauseButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            finish();
                        }
                    });
                    mPauseButton.setText(android.R.string.ok);
                } else {
                    mDashboard.setVisibility(View.VISIBLE);
                    mCellMessage.setVisibility(View.GONE);
                    mStatusText.setText(R.string.text_validation_failed);
                    mPauseButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            finish();
                        }
                    });
                    mPauseButton.setText(android.R.string.cancel);
                }
                super.onPostExecute(result);
            }

        };
        validationTask.execute(new Object());
    }

    /**
     * If the download isn't present, we initialize the download UI. This ties
     * all of the controls into the remote service calls.
     */
    private void initializeDownloadUI() {
        mDownloaderClientStub = DownloaderClientMarshaller.CreateStub
                (this, ExpansionFileDownloaderService.class);
        setContentView(R.layout.activity_main);

        mPB = (ProgressBar) findViewById(R.id.progressBar);
        mStatusText = (TextView) findViewById(R.id.statusText);
        mProgressFraction = (TextView) findViewById(R.id.progressAsFraction);
        mProgressPercent = (TextView) findViewById(R.id.progressAsPercentage);
        mAverageSpeed = (TextView) findViewById(R.id.progressAverageSpeed);
        mTimeRemaining = (TextView) findViewById(R.id.progressTimeRemaining);
        mDashboard = findViewById(R.id.downloaderDashboard);
        mCellMessage = findViewById(R.id.approveCellular);
        mPauseButton = (Button) findViewById(R.id.pauseButton);
        mWiFiSettingsButton = (Button) findViewById(R.id.wifiSettingsButton);

        mPauseButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mStatePaused) {
                    mRemoteService.requestContinueDownload();
                } else {
                    mRemoteService.requestPauseDownload();
                }
                setButtonPausedState(!mStatePaused);
            }
        });

        mWiFiSettingsButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
            }
        });

        Button resumeOnCell = (Button) findViewById(R.id.resumeOverCellular);
        resumeOnCell.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mRemoteService.setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR);
                mRemoteService.requestContinueDownload();
                mCellMessage.setVisibility(View.GONE);
            }
        });

    }

    /**
     * Called when the activity is first create; we wouldn't create a layout in
     * the case where we have the file and are moving to another activity
     * without downloading.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /**
         * Both downloading and validation make use of the "download" UI
         */
        initializeDownloadUI();

        /**
         * Before we do anything, are the files we expect already here and
         * delivered (presumably by Market) For free titles, this is probably
         * worth doing. (so no Market request is necessary)
         */
        if (!expansionFilesDelivered()) {

            try {
                Intent launchIntent = MainActivity.this
                        .getIntent();
                Intent intentToLaunchThisActivityFromNotification = new Intent(
                        MainActivity
                        .this, MainActivity.this.getClass());
                intentToLaunchThisActivityFromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                        Intent.FLAG_ACTIVITY_CLEAR_TOP);
                intentToLaunchThisActivityFromNotification.setAction(launchIntent.getAction());

                if (launchIntent.getCategories() != null) {
                    for (String category : launchIntent.getCategories()) {
                        intentToLaunchThisActivityFromNotification.addCategory(category);
                    }
                }

                // Build PendingIntent used to open this activity from
                // Notification
                PendingIntent pendingIntent = PendingIntent.getActivity(
                        MainActivity.this,
                        0, intentToLaunchThisActivityFromNotification,
                        PendingIntent.FLAG_UPDATE_CURRENT);
                // Request to start the download
                int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this,
                        pendingIntent, ExpansionFileDownloaderService.class);

                if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
                    // The DownloaderService has started downloading the files,
                    // show progress
                    initializeDownloadUI();
                    return;
                } // otherwise, download not needed so we fall through to
                  // starting the movie
            } catch (NameNotFoundException e) {
                Log.e(LOG_TAG, "Cannot find own package! MAYDAY!");
                e.printStackTrace();
            }

        } else {
            validateXAPKZipFiles();
        }

    }

    /**
     * Connect the stub to our service on start.
     */
    @Override
    protected void onStart() {
        if (null != mDownloaderClientStub) {
            mDownloaderClientStub.connect(this);
        }
        super.onStart();
    }

    /**
     * Disconnect the stub from our service on stop
     */
    @Override
    protected void onStop() {
        if (null != mDownloaderClientStub) {
            mDownloaderClientStub.disconnect(this);
        }
        super.onStop();
    }

    /**
     * Critical implementation detail. In onServiceConnected we create the
     * remote service and marshaler. This is how we pass the client information
     * back to the service so the client can be properly notified of changes. We
     * must do this every time we reconnect to the service.
     */
    @Override
    public void onServiceConnected(Messenger m) {
        mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
        mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
    }

    /**
     * The download state should trigger changes in the UI --- it may be useful
     * to show the state as being indeterminate at times. This sample can be
     * considered a guideline.
     */
    @Override
    public void onDownloadStateChanged(int newState) {
        setState(newState);
        boolean showDashboard = true;
        boolean showCellMessage = false;
        boolean paused;
        boolean indeterminate;
        switch (newState) {
            case IDownloaderClient.STATE_IDLE:
                // STATE_IDLE means the service is listening, so it's
                // safe to start making calls via mRemoteService.
                paused = false;
                indeterminate = true;
                break;
            case IDownloaderClient.STATE_CONNECTING:
            case IDownloaderClient.STATE_FETCHING_URL:
                showDashboard = true;
                paused = false;
                indeterminate = true;
                break;
            case IDownloaderClient.STATE_DOWNLOADING:
                paused = false;
                showDashboard = true;
                indeterminate = false;
                break;

            case IDownloaderClient.STATE_FAILED_CANCELED:
            case IDownloaderClient.STATE_FAILED:
            case IDownloaderClient.STATE_FAILED_FETCHING_URL:
            case IDownloaderClient.STATE_FAILED_UNLICENSED:
                paused = true;
                showDashboard = false;
                indeterminate = false;
                break;
            case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
            case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
                showDashboard = false;
                paused = true;
                indeterminate = false;
                showCellMessage = true;
                break;

            case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
                paused = true;
                indeterminate = false;
                break;
            case IDownloaderClient.STATE_PAUSED_ROAMING:
            case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
                paused = true;
                indeterminate = false;
                break;
            case IDownloaderClient.STATE_COMPLETED:
                showDashboard = false;
                paused = false;
                indeterminate = false;
                validateXAPKZipFiles();
                return;
            default:
                paused = true;
                indeterminate = true;
                showDashboard = true;
        }
        int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE;
        if (mDashboard.getVisibility() != newDashboardVisibility) {
            mDashboard.setVisibility(newDashboardVisibility);
        }
        int cellMessageVisibility = showCellMessage ? View.VISIBLE : View.GONE;
        if (mCellMessage.getVisibility() != cellMessageVisibility) {
            mCellMessage.setVisibility(cellMessageVisibility);
        }

        mPB.setIndeterminate(indeterminate);
        setButtonPausedState(paused);
    }

    /**
     * Sets the state of the various controls based on the progressinfo object
     * sent from the downloader service.
     */
    @Override
    public void onDownloadProgress(DownloadProgressInfo progress) {
        mAverageSpeed.setText(getString(R.string.kilobytes_per_second,
                Helpers.getSpeedString(progress.mCurrentSpeed)));
        mTimeRemaining.setText(getString(R.string.time_remaining,
                Helpers.getTimeRemaining(progress.mTimeRemaining)));

        progress.mOverallTotal = progress.mOverallTotal;
        mPB.setMax((int) (progress.mOverallTotal >> 8));
        mPB.setProgress((int) (progress.mOverallProgress >> 8));
        mProgressPercent.setText(Long.toString(progress.mOverallProgress
                * 100 /
                progress.mOverallTotal) + "%");
        mProgressFraction.setText(Helpers.getDownloadProgressString
                (progress.mOverallProgress,
                        progress.mOverallTotal));

    try {
        ZipResourceFile expansionFile = APKExpansionSupport
                .getAPKExpansionZipFile(this, 4, 0);

        ZipEntryRO[] zip = expansionFile.getAllEntries();
        Log.e("", "zip[0].isUncompressed() : " + zip[0].isUncompressed());
        Log.e("",
                "mFile.getAbsolutePath() : "
                        + zip[0].mFile.getAbsolutePath());
        Log.e("", "mFileName : " + zip[0].mFileName);
        Log.e("", "mZipFileName : " + zip[0].mZipFileName);
        Log.e("", "mCompressedLength : " + zip[0].mCompressedLength);

        File file = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "");
        ZipHelper.unzip(zip[0].mZipFileName, file);

        if (file.exists()) {
            Log.e("", "unzipped : " + file.getAbsolutePath());
        }

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

    @Override
    protected void onDestroy() {
        this.mCancelValidation = true;
        super.onDestroy();
    }

}
public类MainActivity扩展活动实现IDownloaderClient{
私有静态最终字符串日志\u TAG=“LVLDownloader”;
私人酒吧;
私有文本视图mStatusText;
私有文本视图mProgressFraction;
私有文本视图mProgressPercent;
私有文本视图mAverageSpeed;
私有文本视图MTIME剩余;
私家视线仪表板;
私有视图消息;
私人按钮和公共按钮;
私人按钮MWIFISETTINGS按钮;
私有布尔值;
私人国家;
私有IDownloaderService mRemoteService;
私有IStub mDownloaderClientStub;
私有无效设置状态(int newState){
if(mState!=newState){
mState=新闻状态;
mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState));
}
}
私有void setButtonPausedState(布尔值已暂停){
mstateplaused=暂停;
int stringResourceID=暂停?R.string.text\u按钮\u恢复:
R.string.text\u按钮\u暂停;
mPauseButton.setText(stringResourceID);
}
/**
*这是一个小助手类,演示了对
*市场提供的扩展APK文件。您可能不希望硬编码
*例如文件长度到可执行文件中…您可能希望
*在应用程序开发期间关闭此代码。
*/
私有静态类XAPKFile{
公众参与;
公开最终版本;
公共最终长文件大小;
XAPKFile(布尔isMain,int文件版本,长文件大小){
missin=isMain;
mFileVersion=文件版本;
mFileSize=文件大小;
}
}
/**
*这里是您放置验证器将用于确定的数据的位置
*如果文件传递正确。这是在源代码中编码的
*因此,应用程序可以轻松确定文件是否已被删除
*无需与服务器对话即可正确交付。如果
*应用程序正在使用LVL进行许可,消除
*这些检查和检查仅依赖于服务器。
*/
私有静态最终XAPKFile[]xAPKS={
新的XAPKFile(
true,//true表示主文件
4,//上载文件的APK版本
//反对
240000L//文件的长度(字节)
),
新的XAPKFile(
true,//false表示修补程序文件
3,//上载修补程序文件的APK版本
//反对
24000L//修补程序文件的长度(字节)
)            
};
/**
*浏览上面结构中定义的每个APK扩展文件
*并确定文件是否存在并匹配所需大小。免费
*应用程序应该明确地考虑这样做,因为这允许
*首次在没有网络的情况下启动的应用程序
*连接存在。使用LVL的付费应用程序可能在
*至少一个需要网络存在的LVL检查,因此
*没有必要。
* 
*@如果存在,则返回true。
*/
布尔ExpansionFileDelivered(){
for(XAPKFile xf:xAPKS){
String fileName=Helpers.getExpansionAPKFileName(this,xf.mismin,xf.mFileVersion);
如果(!Helpers.doesFileExist(this,fileName,xf.mFileSize,false))
返回false;
}
返回true;
}
/**
*计算验证速度的移动平均值,这样我们就不会
*对时间等的跳跃式计算。
*/
静态专用最终浮点平滑系数=0.005f;
/**
*由异步任务使用
*/
私有布尔mCancelValidation;
/**
*浏览每个扩展APK文件,并将每个文件作为zip文件打开。
*计算每个文件的CRC,如果任何文件不匹配,则返回false。
* 
*@如果XAPKZipFile成功,则返回true
*/
void validateXAPKZipFiles(){
AsyncTask validationTask=新建AsyncTask(){
@凌驾
受保护的void onPreExecute(){
mDashboard.setVisibility(View.VISIBLE);
mCellMessage.setVisibility(View.GONE);
mStatusText.setText(R.string.text\u验证\u下载);
mPauseButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
McCancelValidation=真;
}
});
mPauseButton.setText(R.string.text\u按钮\u取消\u验证);
super.onPreExecute();
}
@凌驾
受保护的布尔doInBackground(对象…参数){
for(XAPKFile xf:xAPKS){
字符串文件名=Helpers.getExpansionAPKFileName(
这个,,
xf.mismin,xf.mFileVersion);
如果(!Helpers.doesfile)存在(MainActivity.this,文件名,
xf.mFileSize,false)
返回false;
fileName=助手
.generateSaveFileName(MainActivity.this,文件名);
zrf;
字节[]buf=新字节[1024*256];
试一试{
zrf=新ZipResourceFile(文件名);
ZipEntryRO[]条目=
package com.example.dummy;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import android.util.Log;

public class ZipHelper
{
boolean zipError=false;

public boolean isZipError() {
    return zipError;
}

public void setZipError(boolean zipError) {
    this.zipError = zipError;
}

public void unzip(String archive, File outputDir)
{
    try {
        ZipFile zipfile = new ZipFile(archive);
        //AvazAppActivity.printLog("TOTAL ZIP ENTRIES",zipfile.size()+":");
        for (Enumeration e = zipfile.entries(); e.hasMoreElements(); ) {
            ZipEntry entry = (ZipEntry) e.nextElement();
            unzipEntry(zipfile, entry, outputDir);

        }
    }
    catch (Exception e) {
        setZipError(true);
    }
}

private void unzipEntry(ZipFile zipfile, ZipEntry entry, File outputDir) throws IOException
{
    if (entry.isDirectory()) {
        createDirectory(new File(outputDir, entry.getName()));
        return;
    }

    File outputFile = new File(outputDir, entry.getName());
    if (!outputFile.getParentFile().exists()){
        createDirectory(outputFile.getParentFile());
    }

    //AvazAppActivity.printLog("control","ZipHelper.unzipEntry() - Extracting: " + entry);
    BufferedInputStream inputStream = new BufferedInputStream(zipfile.getInputStream(entry));
    BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));

    try {
        copy(inputStream, outputStream);
    }
    catch (Exception e) {
        setZipError(true);
    }
    finally {
        outputStream.close();
        inputStream.close();
    }
}

private void createDirectory(File dir)
{
    if (!dir.exists()){
        if(!dir.mkdirs()) throw new RuntimeException("Can't create directory "+dir);
    }
    else 
        Log.d("control","ZipHelper.createDir() - Exists directory: "+dir.getName());
}
private void copy(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
      out.write(buffer, 0, read);
    }
}
}
ZipHelper helper = new ZipHelper();
File file = new File("/sdcard/Android/data/"+PACKAGE_NAME+"/");
helper.unzip("/sdcard/Android/obb/"+PACKAGE_NAME+"/main."+ versionCode + "."+PACKAGE_NAME+".obb", file);
    try {
        ZipResourceFile expansionFile = APKExpansionSupport
                .getAPKExpansionZipFile(this, 4, 0);

        ZipEntryRO[] zip = expansionFile.getAllEntries();
        Log.e("", "zip[0].isUncompressed() : " + zip[0].isUncompressed());
        Log.e("",
                "mFile.getAbsolutePath() : "
                        + zip[0].mFile.getAbsolutePath());
        Log.e("", "mFileName : " + zip[0].mFileName);
        Log.e("", "mZipFileName : " + zip[0].mZipFileName);
        Log.e("", "mCompressedLength : " + zip[0].mCompressedLength);

        File file = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "");
        ZipHelper.unzip(zip[0].mZipFileName, file);

        if (file.exists()) {
            Log.e("", "unzipped : " + file.getAbsolutePath());
        }

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

    @Override
    protected void onDestroy() {
        this.mCancelValidation = true;
        super.onDestroy();
    }
 public class ZipHelper {
static boolean zipError = false;

public static boolean isZipError() {
    return zipError;
}

public static void setZipError(boolean zipError) {
    ZipHelper.zipError = zipError;
}

public static void unzip(String archive, File outputDir) {
    try {
        Log.d("control", "ZipHelper.unzip() - File: " + archive);
        ZipFile zipfile = new ZipFile(archive);
        for (Enumeration<? extends ZipEntry> e = zipfile.entries(); e
                .hasMoreElements();) {
            ZipEntry entry = (ZipEntry) e.nextElement();
            unzipEntry(zipfile, entry, outputDir);

        }
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzip() - Error extracting file "
                + archive + ": " + e);
        setZipError(true);
    }
}

private static void unzipEntry(ZipFile zipfile, ZipEntry entry,
        File outputDir) throws IOException {
    if (entry.isDirectory()) {
        createDirectory(new File(outputDir, entry.getName()));
        return;
    }

    File outputFile = new File(outputDir, entry.getName());
    if (!outputFile.getParentFile().exists()) {
        createDirectory(outputFile.getParentFile());
    }

    Log.d("control", "ZipHelper.unzipEntry() - Extracting: " + entry);
    BufferedInputStream inputStream = new BufferedInputStream(
            zipfile.getInputStream(entry));
    BufferedOutputStream outputStream = new BufferedOutputStream(
            new FileOutputStream(outputFile));

    try {
        IOUtils.copy(inputStream, outputStream);
    } catch (Exception e) {
        Log.d("control", "ZipHelper.unzipEntry() - Error: " + e);
        setZipError(true);
    } finally {
        outputStream.close();
        inputStream.close();
    }
}

private static void createDirectory(File dir) {
    Log.d("control",
            "ZipHelper.createDir() - Creating directory: " + dir.getName());
    if (!dir.exists()) {
        if (!dir.mkdirs())
            throw new RuntimeException("Can't create directory " + dir);
    } else
        Log.d("control",
                "ZipHelper.createDir() - Exists directory: "
                        + dir.getName());
}
}