DataExporter.java revision 8a6e02add7c70666cdb506310c134af7d91c323c
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.providers.contacts.debug;
18
19import android.content.Context;
20import android.media.MediaScannerConnection;
21import android.util.Log;
22
23import com.google.common.io.Closeables;
24
25import java.io.File;
26import java.io.FileInputStream;
27import java.io.FileOutputStream;
28import java.io.IOException;
29import java.io.InputStream;
30import java.util.zip.ZipEntry;
31import java.util.zip.ZipOutputStream;
32
33/**
34 * Compress all files under the app data dir into a single zip file.
35 */
36public class DataExporter {
37    private static String TAG = "DataExporter";
38
39    public static final String ZIP_MIME_TYPE = "application/zip";
40
41    /**
42     * Compress all files under the app data dir into a single zip file.
43     */
44    public static void exportData(Context context, File outFile) throws IOException {
45        outFile.delete();
46        Log.i(TAG, "Outfile=" + outFile.getAbsolutePath());
47
48        final ZipOutputStream os = new ZipOutputStream(new FileOutputStream(outFile));
49        try {
50            addDirectory(os, context.getFilesDir().getParentFile(), "contacts-files");
51        } finally {
52            Closeables.closeQuietly(os);
53        }
54        // Tell the media scanner about the new file so that it is
55        // immediately available to the user.
56        MediaScannerConnection.scanFile(context,
57                new String[] {outFile.toString()},
58                new String[] {ZIP_MIME_TYPE}, null);
59    }
60
61    /**
62     * Add all files under {@code current} to {@code os} zip stream
63     */
64    private static void addDirectory(ZipOutputStream os, File current, String storedPath)
65            throws IOException {
66        for (File child : current.listFiles()) {
67            final String childStoredPath = storedPath + "/" + child.getName();
68
69            if (child.isDirectory()) {
70                addDirectory(os, child, childStoredPath);
71            } else if (child.isFile()) {
72                addFile(os, child, childStoredPath);
73            } else {
74                // Shouldn't happen; skip.
75            }
76        }
77    }
78
79    /**
80     * Add a single file {@code current} to {@code os} zip stream using the file name
81     * {@code storedPath}.
82     */
83    private static void addFile(ZipOutputStream os, File current, String storedPath)
84            throws IOException {
85        final InputStream is = new FileInputStream(current);
86        os.putNextEntry(new ZipEntry(storedPath));
87
88        final byte[] buf = new byte[32 * 1024];
89        int totalLen = 0;
90        while (true) {
91            int len = is.read(buf);
92            if (len <= 0) {
93                break;
94            }
95            os.write(buf, 0, len);
96            totalLen += len;
97        }
98        os.closeEntry();
99        Log.i(TAG, "Added " + current.getAbsolutePath() + " as " + storedPath +
100                " (" + totalLen + " bytes)");
101    }
102}
103