Home | History | Annotate | Download | only in testingcamera
      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 
     39     public SnapshotDialogFragment() {
     40         // Empty constructor required for DialogFragment
     41     }
     42 
     43     @Override
     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 
    117     public void updateImage(byte[] image) {
    118         mJpegImage = image;
    119     }
    120 
    121     private String getAttrib(ExifInterface exif, String tag) {
    122         String attribute = exif.getAttribute(tag);
    123         return (attribute == null) ? "???" : attribute;
    124     }
    125 
    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 
    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 
    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
    254     public synchronized void onScanCompleted(String path, Uri uri) {
    255         mSavedUri = uri;
    256         if (mViewWhenReady) viewFile();
    257     }
    258 }
    259