Storage.java revision 595d33f1308089ea4e656e247548a71b218d9fa5
1/*
2 * Copyright (C) 2010 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.camera;
18
19import android.content.ContentResolver;
20import android.content.ContentValues;
21import android.location.Location;
22import android.net.Uri;
23import android.os.Environment;
24import android.os.StatFs;
25import android.provider.MediaStore.Images;
26import android.provider.MediaStore.Images.ImageColumns;
27import android.util.Log;
28
29import java.io.File;
30import java.io.FileOutputStream;
31
32public class Storage {
33    private static final String TAG = "CameraStorage";
34
35    public static final String DCIM =
36            Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString();
37
38    public static final String DIRECTORY = DCIM + "/Camera";
39
40    // Match the code in MediaProvider.computeBucketValues().
41    public static final String BUCKET_ID =
42            String.valueOf(DIRECTORY.toLowerCase().hashCode());
43
44    public static final long UNAVAILABLE = -1L;
45    public static final long PREPARING = -2L;
46    public static final long UNKNOWN_SIZE = -3L;
47
48    private static final int BUFSIZE = 4096;
49
50    public static Uri addImage(ContentResolver resolver, String title,
51            long date, Location location, int orientation, byte[] jpeg) {
52        // Save the image.
53        String path = DIRECTORY + '/' + title + ".jpg";
54        FileOutputStream out = null;
55        try {
56            out = new FileOutputStream(path);
57            out.write(jpeg);
58        } catch (Exception e) {
59            Log.e(TAG, "Failed to write image", e);
60            return null;
61        } finally {
62            try {
63                out.close();
64            } catch (Exception e) {
65            }
66        }
67
68        // Insert into MediaStore.
69        ContentValues values = new ContentValues(9);
70        values.put(ImageColumns.TITLE, title);
71        values.put(ImageColumns.DISPLAY_NAME, title + ".jpg");
72        values.put(ImageColumns.DATE_TAKEN, date);
73        values.put(ImageColumns.MIME_TYPE, "image/jpeg");
74        values.put(ImageColumns.ORIENTATION, orientation);
75        values.put(ImageColumns.DATA, path);
76        values.put(ImageColumns.SIZE, jpeg.length);
77
78        if (location != null) {
79            values.put(ImageColumns.LATITUDE, location.getLatitude());
80            values.put(ImageColumns.LONGITUDE, location.getLongitude());
81        }
82
83        Uri uri = resolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values);
84        if (uri == null) {
85            Log.e(TAG, "Failed to write MediaStore");
86            return null;
87        }
88        return uri;
89    }
90
91    public static long getAvailableSpace() {
92        String state = Environment.getExternalStorageState();
93        Log.d(TAG, "External storage state=" + state);
94        if (Environment.MEDIA_CHECKING.equals(state)) {
95            return PREPARING;
96        }
97        if (!Environment.MEDIA_MOUNTED.equals(state)) {
98            return UNAVAILABLE;
99        }
100
101        File dir = new File(DIRECTORY);
102        dir.mkdirs();
103        if (!dir.isDirectory() || !dir.canWrite()) {
104            return UNAVAILABLE;
105        }
106
107        try {
108            StatFs stat = new StatFs(DIRECTORY);
109            return stat.getAvailableBlocks() * (long) stat.getBlockSize();
110        } catch (Exception e) {
111            Log.i(TAG, "Fail to access external storage", e);
112        }
113        return UNKNOWN_SIZE;
114    }
115
116    /**
117     * OSX requires plugged-in USB storage to have path /DCIM/NNNAAAAA to be
118     * imported. This is a temporary fix for bug#1655552.
119     */
120    public static void ensureOSXCompatible() {
121        File nnnAAAAA = new File(DCIM, "100ANDRO");
122        if (!(nnnAAAAA.exists() || nnnAAAAA.mkdirs())) {
123            Log.e(TAG, "Failed to create " + nnnAAAAA.getPath());
124        }
125    }
126}
127