2013年9月29日日曜日

Androidでパスワード付きZipファイルを展開する方法

2013/11/09 In-Memoryで捌く方法を追記

ライブラリ

Zip4jというライブラリを使用します。
Zip4j - Java library to handle Zip files
http://www.lingala.net/zip4j/

Zip4jのライセンスはApache License, Version 2.0。
Zip4j - About
http://www.lingala.net/zip4j/about.php

プロジェクトにライブラリを追加

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}
apply plugin: 'android'

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 18
    buildToolsVersion "18.0.1"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 18
    }
}

dependencies {
    compile 'net.lingala.zip4j:zip4j:1.3.1'
}

build.gradleにライブラリを追加する時は、こちらのサイトが便利です。
Gradle, please
http://gradleplease.appspot.com/

Zip4jで検索するとこんな感じに表示されますので、あとはbuild.gradleにコピペすればOKです。

Eclipseで開発している場合は下記のページからjarファイルをダウンロードしてlibsディレクトリに配置します。
Zip4j - Java library to handle Zip files
http://www.lingala.net/zip4j/download.php

サンプルコード

package com.example.passzip;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;

public class MainActivity extends Activity {

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

        String zipFilePath = Environment.getExternalStorageDirectory().getPath() + "/PassZip/hoge.zip";
        String destinationPath = Environment.getExternalStorageDirectory().getPath() + "/PassZip/";
        String password = "hoge";
        try {
            ZipFile zipFile = new ZipFile(zipFilePath);
            if (zipFile.isEncrypted()) {
                zipFile.setPassword(password);
            }
            zipFile.extractAll(destinationPath);
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

}
sdcard/PassZip/ディレクトリにあるパスワード付きZipファイルhoge.zipを同じディレクトリに展開するサンプルになっています。
Zipファイルの中身はfoo.txtが入ったhogeディレクトリです。
Zipファイルのパスワードはhogeとします。
外部ストレージに書き込みを行いますのでマニフェストファイルに
android.permission.WRITE_EXTERNAL_STORAGE
の宣言が必要です。

サンプルコードでは簡略化のため、UIスレッド上でZipの展開処理を行っています。
実際にアプリで使用する場合はAsyncTaskなどを使ってUIスレッドをブロックしないようにします。
エラー処理も省略していますので適宜エラー処理を行います。

動作確認

動作確認は
・Xperia Z(Android OS 4.1.2)
・IS14SH(Android OS 2.3.5)
で行いました。

アプリ実行前
アプリ実行後
実機のファイラーアプリからfoo.txtを確認したところ、テキストファイルの内容が表示されましたので正常にパスワード付きZipファイルの展開が行われているようです。

In-Memory(2013/11/09 追記)

上記のサンプルではZipファイルをストレージに展開してから使用しましたが、In-Memoryで捌く方法はこんな感じです。
このサンプルではgetExternalFilesDir()なディレクトリにある、test.zipの中身(ic_launcher.png)を読み込んでImageViewに表示しています。

ZipFile zipFile = null;
FileHeader fileHeader = null;
InputStream inputStream = null;
Bitmap bitmap = null;
try {                                                                         
    zipFile = new ZipFile(getExternalFilesDir(null).getPath() + "/test.zip");
    if (zipFile.isEncrypted()) {                                              
        zipFile.setPassword("password");                                      
    }                                                                         
    String filePath = "ic_launcher.png"; // アーカイブ内のファイルパス                     
    fileHeader = zipFile.getFileHeader(filePath);                             
    inputStream = zipFile.getInputStream(fileHeader);                         
    bitmap = BitmapFactory.decodeStream(inputStream);                         
    inputStream.close();                                                      
} catch (ZipException e) {                                                    
    // TODO: error handling                                                   
} catch (IOException e) {                                                     
    // TODO: error handling                                                   
}                                                                             
                                                                              
ImageView imageView = (ImageView) findViewById(R.id.image_view);              
imageView.setImageBitmap(bitmap);                                             

参考サイト

こちらのサイトを参考にさせていただきました。
ありがとうございます。
shinodogg.com
パスワード付きZipファイルをJava(Zip4j)で
http://shinodogg.com/?p=4601

0 件のコメント:

コメントを投稿