• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.testingcamera;
2 
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.IOException;
6 
7 import android.graphics.Bitmap;
8 import android.graphics.BitmapFactory;
9 import android.media.ExifInterface;
10 import android.media.MediaScannerConnection.OnScanCompletedListener;
11 import android.net.Uri;
12 import android.os.AsyncTask;
13 import android.os.Bundle;
14 import android.app.DialogFragment;
15 import android.content.Intent;
16 import android.text.method.ScrollingMovementMethod;
17 import android.view.LayoutInflater;
18 import android.view.View;
19 import android.view.View.OnClickListener;
20 import android.view.ViewGroup;
21 import android.widget.Button;
22 import android.widget.ImageView;
23 import android.widget.TextView;
24 
25 class SnapshotDialogFragment extends DialogFragment
26                 implements OnScanCompletedListener{
27 
28     private ImageView mInfoImage;
29     private TextView mInfoText;
30     private Button mOkButton;
31     private Button mSaveButton;
32     private Button mSaveAndViewButton;
33 
34     private byte[] mJpegImage;
35     private boolean mSaved = false;
36     private boolean mViewWhenReady = false;
37         private Uri mSavedUri = null;
38 
SnapshotDialogFragment()39     public SnapshotDialogFragment() {
40         // Empty constructor required for DialogFragment
41     }
42 
43     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)44     public View onCreateView(LayoutInflater inflater, ViewGroup container,
45             Bundle savedInstanceState) {
46         View view = inflater.inflate(R.layout.fragment_snapshot, container);
47 
48         mOkButton = (Button) view.findViewById(R.id.snapshot_ok);
49         mOkButton.setOnClickListener(mOkButtonListener);
50 
51         mSaveButton = (Button) view.findViewById(R.id.snapshot_save);
52         mSaveButton.setOnClickListener(mSaveButtonListener);
53 
54         mSaveAndViewButton = (Button) view.findViewById(R.id.snapshot_view);
55         mSaveAndViewButton.setOnClickListener(mSaveAndViewButtonListener);
56 
57         mInfoImage = (ImageView) view.findViewById(R.id.snapshot_image);
58         mInfoText= (TextView) view.findViewById(R.id.snapshot_text);
59         mInfoText.setMovementMethod(new ScrollingMovementMethod());
60 
61         if (mJpegImage != null) {
62             new AsyncTask<byte[], Integer, Bitmap>() {
63                 @Override
64                 protected Bitmap doInBackground(byte[]... params) {
65                     byte[] jpegImage = params[0];
66                     BitmapFactory.Options opts = new BitmapFactory.Options();
67                     opts.inJustDecodeBounds = true;
68                     BitmapFactory.decodeByteArray(jpegImage, 0,
69                             jpegImage.length, opts);
70                     // Keep image at less than 1 MP.
71                     if (opts.outWidth > 1024 || opts.outHeight > 1024) {
72                         int scaleFactorX = opts.outWidth / 1024 + 1;
73                         int scaleFactorY = opts.outHeight / 1024 + 1;
74                         int scaleFactor = scaleFactorX > scaleFactorY ?
75                             scaleFactorX : scaleFactorY;
76                         opts.inSampleSize = scaleFactor;
77                     }
78                     opts.inJustDecodeBounds = false;
79                     Bitmap img = BitmapFactory.decodeByteArray(jpegImage, 0,
80                             jpegImage.length, opts);
81                     return img;
82                 }
83 
84                 @Override
85                 protected void onPostExecute(Bitmap img) {
86                     mInfoImage.setImageBitmap(img);
87                 }
88             }.execute(mJpegImage);
89         }
90 
91         getDialog().setTitle("Snapshot result");
92         return view;
93     }
94 
95     public OnClickListener mOkButtonListener = new OnClickListener() {
96         @Override
97         public void onClick(View v) {
98             dismiss();
99         }
100     };
101 
102     public OnClickListener mSaveButtonListener = new OnClickListener() {
103         @Override
104         public void onClick(View v) {
105             saveFile();
106         }
107     };
108 
109     public OnClickListener mSaveAndViewButtonListener = new OnClickListener() {
110         @Override
111         public void onClick(View v) {
112             saveFile();
113             viewFile();
114         }
115     };
116 
updateImage(byte[] image)117     public void updateImage(byte[] image) {
118         mJpegImage = image;
119     }
120 
getAttrib(ExifInterface exif, String tag)121     private String getAttrib(ExifInterface exif, String tag) {
122         String attribute = exif.getAttribute(tag);
123         return (attribute == null) ? "???" : attribute;
124     }
125 
saveFile()126     private void saveFile() {
127         if (!mSaved) {
128             TestingCamera parent = (TestingCamera) getActivity();
129             parent.log("Saving image");
130 
131             File targetFile = parent.getOutputMediaFile(TestingCamera.MEDIA_TYPE_IMAGE);
132             if (targetFile == null) {
133                 parent.logE("Unable to create file name");
134                 return;
135             }
136             parent.logIndent(1);
137             parent.log("File name: " + targetFile.toString());
138             try {
139                 FileOutputStream out = new FileOutputStream(targetFile);
140                 out.write(mJpegImage);
141                 out.close();
142                 mSaved = true;
143                 parent.notifyMediaScannerOfFile(targetFile, this);
144                 updateExif(targetFile);
145             } catch (IOException e) {
146                 parent.logE("Unable to save file: " + e.getMessage());
147             }
148             parent.logIndent(-1);
149         }
150     }
151 
updateExif(File targetFile)152     private void updateExif(File targetFile) {
153         ((TestingCamera) getActivity()).log("Extracting EXIF");
154         try {
155             ExifInterface exif = new ExifInterface(targetFile.toString());
156 
157             String aperture = getAttrib(exif, ExifInterface.TAG_APERTURE);
158 
159             String dateTime = getAttrib(exif, ExifInterface.TAG_DATETIME);
160             String exposureTime = getAttrib(exif, ExifInterface.TAG_EXPOSURE_TIME);
161             int flash = exif.getAttributeInt(ExifInterface.TAG_FLASH, 0);
162             double focalLength = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0);
163 
164             double gpsAltitude = exif.getAltitude(Double.NaN);
165             String gpsDatestamp = getAttrib(exif, ExifInterface.TAG_GPS_DATESTAMP);
166             float[] gpsCoords = new float[2];
167             if (!exif.getLatLong(gpsCoords)) {
168                 gpsCoords[0] = Float.NaN;
169                 gpsCoords[1] = Float.NaN;
170             }
171             String gpsProcessingMethod = getAttrib(exif, ExifInterface.TAG_GPS_PROCESSING_METHOD);
172             String gpsTimestamp = getAttrib(exif, ExifInterface.TAG_GPS_TIMESTAMP);
173 
174             int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
175             int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
176             String iso = getAttrib(exif, ExifInterface.TAG_ISO);
177             String make = getAttrib(exif, ExifInterface.TAG_MAKE);
178             String model = getAttrib(exif, ExifInterface.TAG_MODEL);
179             int orientationVal = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
180             int whiteBalance = exif.getAttributeInt(ExifInterface.TAG_WHITE_BALANCE, 0);
181 
182             final String[] orientationStrings= new String[] {
183                 "UNDEFINED",
184                 "NORMAL",
185                 "FLIP_HORIZONTAL",
186                 "ROTATE_180",
187                 "FLIP_VERTICAL",
188                 "TRANSPOSE",
189                 "ROTATE_90",
190                 "TRANSVERSE",
191                 "ROTATE_270"
192             };
193             if (orientationVal >= orientationStrings.length) {
194                 orientationVal = 0;
195             }
196             String orientation = orientationStrings[orientationVal];
197 
198             StringBuilder exifInfo = new StringBuilder();
199             exifInfo.append("EXIF information for ").
200                 append(targetFile.toString()).append("\n\n");
201             exifInfo.append("Size: ").
202                 append(width).append(" x ").append(height).append("\n");
203             exifInfo.append("Make: ").
204                 append(make).append("\n");
205             exifInfo.append("Model: ").
206                 append(model).append("\n");
207             exifInfo.append("Orientation: ").
208                 append(orientation).append("\n");
209             exifInfo.append("Aperture: ").
210                 append(aperture).append("\n");
211             exifInfo.append("Focal length: ").
212                 append(focalLength).append("\n");
213             exifInfo.append("Exposure time: ").
214                 append(exposureTime).append("\n");
215             exifInfo.append("ISO: ").
216                 append(iso).append("\n");
217             exifInfo.append("Flash: ").
218                 append(flash).append("\n");
219             exifInfo.append("White balance: ").
220                 append(whiteBalance).append("\n");
221             exifInfo.append("Date/Time: ").
222                 append(dateTime).append("\n");
223             exifInfo.append("GPS altitude: ").
224                 append(gpsAltitude).append("\n");
225             exifInfo.append("GPS latitude: ").
226                 append(gpsCoords[0]).append("\n");
227             exifInfo.append("GPS longitude: ").
228                 append(gpsCoords[1]).append("\n");
229             exifInfo.append("GPS datestamp: ").
230                 append(gpsDatestamp).append("\n");
231             exifInfo.append("GPS timestamp: ").
232                 append(gpsTimestamp).append("\n");
233             exifInfo.append("GPS processing method: ").
234                 append(gpsProcessingMethod).append("\n");
235             mInfoText.setText(exifInfo.toString());
236 
237         } catch (IOException e) {
238             ((TestingCamera) getActivity()).logE("Unable to extract EXIF: " + e.getMessage());
239         }
240     }
241 
viewFile()242     private synchronized void viewFile() {
243         if (!mSaved) return;
244         if (mSavedUri != null) {
245             ((TestingCamera) getActivity()).log("Viewing file");
246             mViewWhenReady = false;
247             getActivity().startActivity(new Intent(Intent.ACTION_VIEW, mSavedUri));
248         } else {
249             mViewWhenReady = true;
250         }
251     }
252 
253     @Override
onScanCompleted(String path, Uri uri)254     public synchronized void onScanCompleted(String path, Uri uri) {
255         mSavedUri = uri;
256         if (mViewWhenReady) viewFile();
257     }
258 }
259