Android　Zipで固めた画像をダウンロードして表示する

複数の画像をダウンロードしてImageViewに反映するよりも、
Zipで固めたファイルをダウンロードする方がリクエストも1回で済むので、
エラー処理とか考えなくていいし楽な場合がある。


#### レイアウトファイル
レイアウトファイルは適当にボタンと、展開した画像を表示するためのImaveViewを置く。

```xml:activity_main.xml
<ScrollView 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" >

    <RelativeLayout
        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=".MainActivity" >

        <LinearLayout
            android:id="@+id/layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:orientation="vertical">
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:text="ZIPダウンロード＆解答" />
                <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="画像削除" />
            </LinearLayout>

        <ImageView
            android:id="@+id/image1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/layout"
            android:layout_centerInParent="true"
            android:src="@drawable/ic_launcher"
            android:layout_marginBottom="15dp"
            android:scaleType="center"/>

        <ImageView
            android:id="@+id/image2"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_below="@id/image1"
            android:layout_centerInParent="true"
            android:src="@drawable/ic_launcher"
            android:scaleType="center"/>
    </RelativeLayout>

</ScrollView>
```

#### Zipで固めた画像をダウンロードするクラスを作成
今回はダウンロードするクラスをAsyncTaskLoaderで実装。

```java:ZipDownloadTaskLoader.java
public class ZipDownloadTaskLoader extends AsyncTaskLoader<String> {

    public ZipDownloadTaskLoader(Context context) {
        super(context);
    }

    @Override
    public String loadInBackground() {

        try {
            Log.i("", "start download");
            // URL設定
            URL url = new URL("http://xxxxx.com/sample.zip");

            // HTTP接続開始
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            // テンポラリファイルの設定
            File outputFile = File.createTempFile("sample", ".zip");
            FileOutputStream fos = new FileOutputStream(outputFile);

            // ダウンロード開始
            InputStream is = connection.getInputStream();
            byte[] buffer = new byte[1024];
            int len = 0;

            while ((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }

            fos.close();
            is.close();

            // ダウンロードした画像ファイルのパスを返す
            return outputFile.getPath();
        } catch (IOException e) {
            e.printStackTrace();

            // エラーの場合nullを返す
            return null;
        }

    }

}

```

#### Zipを解凍しディレクトリに展開する
```java:ZipUtil.java
public class ZipUtil {

    public static List<String> extract(Context context, String filename) {
        ZipInputStream in = null;
        BufferedOutputStream out = null;
     
        ZipEntry zipEntry = null;
        int len = 0;
        List<String> list = new ArrayList<String>();
         
        try {
            in = new ZipInputStream(new FileInputStream(filename));
     
            // ZIPファイルに含まれるエントリに対して順にアクセス
            while ((zipEntry = in.getNextEntry()) != null) {
                File newfile = new File(zipEntry.getName());
                
                // 出力用ファイルストリームの生成
                FileOutputStream file = new FileOutputStream(context.getFilesDir() + "/" + newfile.getName());
                out = new BufferedOutputStream(file);
                String path = context.getFilesDir() + "/" + newfile.getName();
                // エントリの内容を出力
                byte[] buffer = new byte[1024];
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
     
                in.closeEntry();
                out.close();
                out = null;
                list.add(path);
            }
            return list;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }
}
```


#### ダウンロードしてファイルを解凍しImageViewにつける
```java:Main.java
public class MainActivity extends FragmentActivity implements LoaderCallbacks<String> {

    private ImageView mImageView1;
    private ImageView mImageView2;
    private ProgressDialog mDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1 = (Button) findViewById(R.id.button1);
        Button button2 = (Button) findViewById(R.id.button2);
        mImageView1 = (ImageView) findViewById(R.id.image1);
        mImageView2 = (ImageView) findViewById(R.id.image2);
        button1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                getSupportLoaderManager().initLoader(0, new Bundle(), MainActivity.this);
            }
        });
        button2.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                mImageView1.setImageBitmap(null);
                mImageView2.setImageBitmap(null);
                
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public Loader<String> onCreateLoader(int arg0, Bundle arg1) {
        // TODO Auto-generated method stub
        Log.i("", "oncreateLoader");
        ZipDownloadTaskLoader loader = new ZipDownloadTaskLoader(getApplicationContext());
        loader.forceLoad();
        mDialog = ProgressDialog.show(this, "", "画像取得中");
        return loader;
    }

    @Override
    public void onLoadFinished(Loader<String> arg0, String arg1) {
        Log.i("", "end download");
        Log.i("", "start unzip");
        mDialog.dismiss();
        List<String> list = ZipUtil.extract(getApplicationContext(), arg1);
        if (list.isEmpty()) {
            Toast.makeText(getApplicationContext(), "失敗", Toast.LENGTH_SHORT).show();
            return;
        }
        
        Bitmap bitmap1 = BitmapFactory.decodeFile(list.get(0));
        Bitmap bitmap2 = BitmapFactory
                .decodeFile(list.get(1));
        mImageView1.setImageBitmap(bitmap1);
        mImageView2.setImageBitmap(bitmap2);
        mImageView1.setScaleType(ImageView.ScaleType.FIT_XY);
        mImageView2.setScaleType(ImageView.ScaleType.FIT_XY);

        bitmap1 = null;
        bitmap2 = null;
    }

    @Override
    public void onLoaderReset(Loader<String> arg0) {
        // TODO Auto-generated method stub

    }

}

```