Android应用程序拍照并显示元数据

时间:2013-08-29 00:38:41

标签: android

我的应用程序编译和一切,但当我尝试在我的模拟器上运行它时,它会弹出一个屏幕强制关闭我的应用程序。请帮忙!

我的代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
       <Button
             android:id="@+id/button1"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:text="@string/openCamera" />
       <ImageView
             android:src="@android:drawable/ic_menu_gallery"
             android:layout_width="fill_parent"
             android:layout_height="300.0dp"
             android:id="@+id/imageView1"
             android:adjustViewBounds="true" />
    </LinearLayout>

这是我的活动:

    import java.io.IOException;
    import java.text.ParsePosition;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;

    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.media.ExifInterface;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;


   public class MainActivity extends Activity {
private static final int CAMERA_REQUEST = 1888; 
private ImageView imageView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    this.imageView = (ImageView)this.findViewById(R.id.imageView1);
    Button photoButton = (Button) this.findViewById(R.id.button1);
    photoButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
            startActivityForResult(cameraIntent, CAMERA_REQUEST); 
        }
    });
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {  
        Bitmap photo = (Bitmap) data.getExtras().get("data"); 
        imageView.setImageBitmap(photo);

    }


}

        // The Exif tag names
        public static final String TAG_ORIENTATION = "Orientation";
        public static final String TAG_DATETIME = "DateTime";
        public static final String TAG_IMAGE_WIDTH = "ImageWidth";
        public static final String TAG_IMAGE_LENGTH = "ImageLength";
        public static final String TAG_GPS_LATITUDE = "GPSLatitude";
        public static final String TAG_GPS_LONGITUDE = "GPSLongitude";
        public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
        public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
        public static final String TAG_WHITE_BALANCE = "WhiteBalance";

        // Constants used for the Orientation Exif tag.
        public static final int ORIENTATION_UNDEFINED = 0;
        public static final int ORIENTATION_NORMAL = 1;
        public static final int ORIENTATION_FLIP_HORIZONTAL = 2;  // left right reversed mirror
        public static final int ORIENTATION_ROTATE_180 = 3;
        public static final int ORIENTATION_FLIP_VERTICAL = 4;  // upside down mirror
        public static final int ORIENTATION_TRANSPOSE = 5;  // flipped about top-left <--> bottom-right axis
        public static final int ORIENTATION_ROTATE_90 = 6;  // rotate 90 cw to right it
        public static final int ORIENTATION_TRANSVERSE = 7;  // flipped about top-right <--> bottom-left axis
        public static final int ORIENTATION_ROTATE_270 = 8;  // rotate 270 to right it

        // Constants used for white balance
        public static final int WHITEBALANCE_AUTO = 0;
        public static final int WHITEBALANCE_MANUAL = 1;

        static {
            System.loadLibrary("exif");
        }

        private String mFilename;
        private HashMap<String, String> mAttributes;
        private boolean mHasThumbnail;

        // Because the underlying implementation (jhead) uses static variables,
        // there can only be one user at a time for the native functions (and
        // they cannot keep state in the native code across function calls). We
        // use sLock to serialize the accesses.
        private static Object sLock = new Object();

        /**
         * Reads Exif tags from the specified JPEG file.
         */
        public MainActivity(String filename) throws IOException {
            mFilename = filename;
            loadAttributes();
        }

        /**
         * Returns the value of the specified tag or {@code null} if there
         * is no such tag in the JPEG file.
         *
         * @param tag the name of the tag.
         */
        public String getAttribute(String tag) {
            return mAttributes.get(tag);
        }

        /**
         * Returns the integer value of the specified tag. If there is no such tag
         * in the JPEG file or the value cannot be parsed as integer, return
         * <var>defaultValue</var>.
         *
         * @param tag the name of the tag.
         * @param defaultValue the value to return if the tag is not available.
         */
        public int getAttributeInt(String tag, int defaultValue) {
            String value = mAttributes.get(tag);
            if (value == null) return defaultValue;
            try {
                return Integer.valueOf(value);
            } catch (NumberFormatException ex) {
                return defaultValue;
            }
        }

        /**
         * Set the value of the specified tag.
         *
         * @param tag the name of the tag.
         * @param value the value of the tag.
         */
        public void setAttribute(String tag, String value) {
            mAttributes.put(tag, value);
        }

        /**
         * Initialize mAttributes with the attributes from the file mFilename.
         *
         * mAttributes is a HashMap which stores the Exif attributes of the file.
         * The key is the standard tag name and the value is the tag's value: e.g.
         * Model -> Nikon. Numeric values are stored as strings.
         *
         * This function also initialize mHasThumbnail to indicate whether the
         * file has a thumbnail inside.
         */
        private void loadAttributes() throws IOException {
            // format of string passed from native C code:
            // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
            // example:
            // "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"
            mAttributes = new HashMap<String, String>();

            String attrStr;
            synchronized (sLock) {
                attrStr = getAttributesNative(mFilename);
            }

            // get count
            int ptr = attrStr.indexOf(' ');
            int count = Integer.parseInt(attrStr.substring(0, ptr));
            // skip past the space between item count and the rest of the attributes
            ++ptr;

            for (int i = 0; i < count; i++) {
                // extract the attribute name
                int equalPos = attrStr.indexOf('=', ptr);
                String attrName = attrStr.substring(ptr, equalPos);
                ptr = equalPos + 1;     // skip past =

                // extract the attribute value length
                int lenPos = attrStr.indexOf(' ', ptr);
                int attrLen = Integer.parseInt(attrStr.substring(ptr, lenPos));
                ptr = lenPos + 1;       // skip pas the space

                // extract the attribute value
                String attrValue = attrStr.substring(ptr, ptr + attrLen);
                ptr += attrLen;

                if (attrName.equals("hasThumbnail")) {
                    mHasThumbnail = attrValue.equalsIgnoreCase("true");
                } else {
                    mAttributes.put(attrName, attrValue);
                }
            }
        }

        /**
         * Save the tag data into the JPEG file. This is expensive because it involves
         * copying all the JPG data from one file to another and deleting the old file
         * and renaming the other. It's best to use {@link      #setAttribute(String,String)}
         * to set all attributes to write and make a single call rather than multiple
         * calls for each attribute.
         */
        public void saveAttributes() throws IOException {
            // format of string passed to native C code:
            // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
            // example:
            // "4 attrPtr ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO"
            StringBuilder sb = new StringBuilder();
            int size = mAttributes.size();
            if (mAttributes.containsKey("hasThumbnail")) {
                --size;
            }
            sb.append(size + " ");
            for (Map.Entry<String, String> iter : mAttributes.entrySet()) {
                String key = iter.getKey();
                if (key.equals("hasThumbnail")) {
                    // this is a fake attribute not saved as an exif tag
                    continue;
                }
                String val = iter.getValue();
                sb.append(key + "=");
                sb.append(val.length() + " ");
                sb.append(val);
            }
            String s = sb.toString();
            synchronized (sLock) {
                saveAttributesNative(mFilename, s);
                commitChangesNative(mFilename);
            }
        }

        /**
         * Returns true if the JPEG file has a thumbnail.
         */
        public boolean hasThumbnail() {
            return mHasThumbnail;
        }

        /**
         * Returns the thumbnail inside the JPEG file, or {@code null} if there is no thumbnail.
         * The returned data is in JPEG format and can be decoded using
         * {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}
         */
        public byte[] getThumbnail() {
            synchronized (sLock) {
                return getThumbnailNative(mFilename);
            }
        }

        /**
         * Stores the latitude and longitude value in a float array. The first element is
         * the latitude, and the second element is the longitude. Returns false if the
         * Exif tags are not available.
         */
        public boolean getLatLong(float output[]) {
            String latValue = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE);
            String latRef = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE_REF);
            String lngValue = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE);
            String lngRef = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE_REF);

            if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
                output[0] = convertRationalLatLonToFloat(latValue, latRef);
                output[1] = convertRationalLatLonToFloat(lngValue, lngRef);
                return true;
            } else {
                return false;
            }
        }

        private static SimpleDateFormat sFormatter =
                new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");

        /**
         * Returns number of milliseconds since Jan. 1, 1970, midnight GMT.
         * Returns -1 if the date time information if not available.
         * @hide
         */
        public long getDateTime() {
            String dateTimeString = mAttributes.get(TAG_DATETIME);
            if (dateTimeString == null) return -1;

            ParsePosition pos = new ParsePosition(0);
            try {
                Date date = sFormatter.parse(dateTimeString, pos);
                if (date == null) return -1;
                return date.getTime();
            } catch (IllegalArgumentException ex) {
                return -1;
            }
        }

        private static float convertRationalLatLonToFloat(
                String rationalString, String ref) {
            try {
                String [] parts = rationalString.split(",");

                String [] pair;
                pair = parts[0].split("/");
                int degrees = (int) (Float.parseFloat(pair[0].trim())
                        / Float.parseFloat(pair[1].trim()));

                pair = parts[1].split("/");
                int minutes = (int) ((Float.parseFloat(pair[0].trim())
                        / Float.parseFloat(pair[1].trim())));

                pair = parts[2].split("/");
                float seconds = Float.parseFloat(pair[0].trim())
                        / Float.parseFloat(pair[1].trim());

                float result = degrees + (minutes / 60F) + (seconds / (60F * 60F));
                if ((ref.equals("S") || ref.equals("W"))) {
                    return -result;
                }
                return result;
            } catch (RuntimeException ex) {
                // if for whatever reason we can't parse the lat long then return
                // null
                return 0f;
            }
        }

        private native boolean appendThumbnailNative(String fileName,
                String thumbnailFileName);

        private native void saveAttributesNative(String fileName,
                String compressedAttributes);

        private native String getAttributesNative(String fileName);

        private native void commitChangesNative(String fileName);

        private native byte[] getThumbnailNative(String fileName);


    }

任何帮助将不胜感激!我真的被困在这一个!提前谢谢!

0 个答案:

没有答案