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 public 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                 protected void onPostExecute(Bitmap img) {
     85                     mInfoImage.setImageBitmap(img);
     86                 }
     87             }.execute(mJpegImage);
     88         }
     89 
     90         getDialog().setTitle("Snapshot result");
     91         return view;
     92     }
     93 
     94     public OnClickListener mOkButtonListener = new OnClickListener() {
     95         public void onClick(View v) {
     96             dismiss();
     97         }
     98     };
     99 
    100     public OnClickListener mSaveButtonListener = new OnClickListener() {
    101         public void onClick(View v) {
    102             saveFile();
    103         }
    104     };
    105 
    106     public OnClickListener mSaveAndViewButtonListener = new OnClickListener() {
    107         public void onClick(View v) {
    108             saveFile();
    109             viewFile();
    110         }
    111     };
    112 
    113     public void updateImage(byte[] image) {
    114         mJpegImage = image;
    115     }
    116 
    117     private String getAttrib(ExifInterface exif, String tag) {
    118         String attribute = exif.getAttribute(tag);
    119         return (attribute == null) ? "???" : attribute;
    120     }
    121 
    122     private void saveFile() {
    123         if (!mSaved) {
    124             TestingCamera parent = (TestingCamera) getActivity();
    125             parent.log("Saving image");
    126 
    127             File targetFile = parent.getOutputMediaFile(TestingCamera.MEDIA_TYPE_IMAGE);
    128             if (targetFile == null) {
    129                 parent.logE("Unable to create file name");
    130                 return;
    131             }
    132             parent.logIndent(1);
    133             parent.log("File name: " + targetFile.toString());
    134             try {
    135                 FileOutputStream out = new FileOutputStream(targetFile);
    136                 out.write(mJpegImage);
    137                 out.close();
    138                 mSaved = true;
    139                 parent.notifyMediaScannerOfFile(targetFile, this);
    140                 updateExif(targetFile);
    141             } catch (IOException e) {
    142                 parent.logE("Unable to save file: " + e.getMessage());
    143             }
    144             parent.logIndent(-1);
    145         }
    146     }
    147 
    148     private void updateExif(File targetFile) {
    149         ((TestingCamera) getActivity()).log("Extracting EXIF");
    150         try {
    151             ExifInterface exif = new ExifInterface(targetFile.toString());
    152 
    153             String aperture = getAttrib(exif, ExifInterface.TAG_APERTURE);
    154 
    155             String dateTime = getAttrib(exif, ExifInterface.TAG_DATETIME);
    156             String exposureTime = getAttrib(exif, ExifInterface.TAG_EXPOSURE_TIME);
    157             int flash = exif.getAttributeInt(ExifInterface.TAG_FLASH, 0);
    158             double focalLength = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, 0);
    159 
    160             double gpsAltitude = exif.getAltitude(Double.NaN);
    161             String gpsDatestamp = getAttrib(exif, ExifInterface.TAG_GPS_DATESTAMP);
    162             float[] gpsCoords = new float[2];
    163             if (!exif.getLatLong(gpsCoords)) {
    164                 gpsCoords[0] = Float.NaN;
    165                 gpsCoords[1] = Float.NaN;
    166             }
    167             String gpsProcessingMethod = getAttrib(exif, ExifInterface.TAG_GPS_PROCESSING_METHOD);
    168             String gpsTimestamp = getAttrib(exif, ExifInterface.TAG_GPS_TIMESTAMP);
    169 
    170             int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
    171             int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
    172             String iso = getAttrib(exif, ExifInterface.TAG_ISO);
    173             String make = getAttrib(exif, ExifInterface.TAG_MAKE);
    174             String model = getAttrib(exif, ExifInterface.TAG_MODEL);
    175             int orientationVal = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
    176             int whiteBalance = exif.getAttributeInt(ExifInterface.TAG_WHITE_BALANCE, 0);
    177 
    178             final String[] orientationStrings= new String[] {
    179                 "UNDEFINED",
    180                 "NORMAL",
    181                 "FLIP_HORIZONTAL",
    182                 "ROTATE_180",
    183                 "FLIP_VERTICAL",
    184                 "TRANSPOSE",
    185                 "ROTATE_90",
    186                 "TRANSVERSE",
    187                 "ROTATE_270"
    188             };
    189             if (orientationVal >= orientationStrings.length) {
    190                 orientationVal = 0;
    191             }
    192             String orientation = orientationStrings[orientationVal];
    193 
    194             StringBuilder exifInfo = new StringBuilder();
    195             exifInfo.append("EXIF information for ").
    196                 append(targetFile.toString()).append("\n\n");
    197             exifInfo.append("Size: ").
    198                 append(width).append(" x ").append(height).append("\n");
    199             exifInfo.append("Make: ").
    200                 append(make).append("\n");
    201             exifInfo.append("Model: ").
    202                 append(model).append("\n");
    203             exifInfo.append("Orientation: ").
    204                 append(orientation).append("\n");
    205             exifInfo.append("Aperture: ").
    206                 append(aperture).append("\n");
    207             exifInfo.append("Focal length: ").
    208                 append(focalLength).append("\n");
    209             exifInfo.append("Exposure time: ").
    210                 append(exposureTime).append("\n");
    211             exifInfo.append("ISO: ").
    212                 append(iso).append("\n");
    213             exifInfo.append("Flash: ").
    214                 append(flash).append("\n");
    215             exifInfo.append("White balance: ").
    216                 append(whiteBalance).append("\n");
    217             exifInfo.append("Date/Time: ").
    218                 append(dateTime).append("\n");
    219             exifInfo.append("GPS altitude: ").
    220                 append(gpsAltitude).append("\n");
    221             exifInfo.append("GPS latitude: ").
    222                 append(gpsCoords[0]).append("\n");
    223             exifInfo.append("GPS longitude: ").
    224                 append(gpsCoords[1]).append("\n");
    225             exifInfo.append("GPS datestamp: ").
    226                 append(gpsDatestamp).append("\n");
    227             exifInfo.append("GPS timestamp: ").
    228                 append(gpsTimestamp).append("\n");
    229             exifInfo.append("GPS processing method: ").
    230                 append(gpsProcessingMethod).append("\n");
    231             mInfoText.setText(exifInfo.toString());
    232 
    233         } catch (IOException e) {
    234             ((TestingCamera) getActivity()).logE("Unable to extract EXIF: " + e.getMessage());
    235         }
    236     }
    237 
    238     private synchronized void viewFile() {
    239         if (!mSaved) return;
    240         if (mSavedUri != null) {
    241             ((TestingCamera) getActivity()).log("Viewing file");
    242             mViewWhenReady = false;
    243             getActivity().startActivity(new Intent(Intent.ACTION_VIEW, mSavedUri));
    244         } else {
    245             mViewWhenReady = true;
    246         }
    247     }
    248 
    249     public synchronized void onScanCompleted(String path, Uri uri) {
    250         mSavedUri = uri;
    251         if (mViewWhenReady) viewFile();
    252     }
    253 }
    254