Androidでパスワード付きzipを生成する
Java Zipユーティリティークラス (Hishidama's Java Zip class)のhmzip16.jarをdarty hackする必要がある。
hmzip16.jarはAndroidで使うことができない
ダウンロードしてきたjarをそのまま使おうとすると java.lang.VerifyErrorが発生する。このExceptionは実行しようとしているクラスファイル(バイトコード)がおかしい時に発生するらしい。
仕方ないので、jarを展開してEclipse/ADTにソースをインポートしてみると、InfoZIP_Native.javaでシンタックスエラーが出ていた。Androidでは用意されていないメソッド(java.io.File#canExecute())が使われているのが原因ということか。
仕方ないのでdarty hackする
- 前述のjarをダウンロードしてきて、アーカイブを展開。
- *.classを削除
- InfoZIP_Native.javaを開き、120行目あたりの if (f.canExecute()) とやっているブロックをコメントアウトし、コンパイル
修正済みのソースとjarの配布
修正済みのソースとjarをAndroid用Zipユーティリティクラス - terurou memoに置いておきました。前述の修正と共に、ソースのエンコーディングをCP932からUTF-8に変えておきました。
ライセンスはオリジナルのhmzip16.jarに従います。
サンプルコード
オンメモリでzipを生成するサンプルをやっつけで書いた。
byte[] bytes; ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); ZipOutputStream zipStream = new ZipOutputStream(byteStream, "UTF-8"); try { zipStream.setPassword("password".getBytes("UTF-8")); zipStream.putNextEntry(new ZipEntry("foo.txt")); zipStream.write("ほげほげ".getBytes("UTF-8")); zipStream.finish(); bytes = byteStream.toByteArray(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); throw new RuntimeException(e); //FIXME } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); //FIXME } finally { try { zipStream.close(); } catch (IOException e) { } } // 以下、bytesをごにょごにょ