summaryrefslogtreecommitdiffstats
path: root/src/com/android
diff options
context:
space:
mode:
authorAngus Kong <shkong@google.com>2013-03-26 11:40:40 -0700
committerAngus Kong <shkong@google.com>2013-03-26 15:42:36 -0700
commit0d00a8907096b9970ac64f52abbd2bfc1ed751b6 (patch)
treebd92779ff5810d46128c0f11a7a84c78ad52d35f /src/com/android
parent88efa27609d08a749cda7ba928cb825de71a7f2b (diff)
downloadandroid_packages_apps_Snap-0d00a8907096b9970ac64f52abbd2bfc1ed751b6.tar.gz
android_packages_apps_Snap-0d00a8907096b9970ac64f52abbd2bfc1ed751b6.tar.bz2
android_packages_apps_Snap-0d00a8907096b9970ac64f52abbd2bfc1ed751b6.zip
Add GPSDirection tag using ExifInterface.
bug:8115825 Change-Id: Iefcbbddbb7f9fed0c386214b428d4743f67d0dd9
Diffstat (limited to 'src/com/android')
-rw-r--r--src/com/android/camera/Exif.java37
-rw-r--r--src/com/android/camera/MediaSaveService.java14
-rw-r--r--src/com/android/camera/PhotoModule.java86
-rw-r--r--src/com/android/camera/Storage.java17
-rw-r--r--src/com/android/camera/VideoModule.java8
5 files changed, 129 insertions, 33 deletions
diff --git a/src/com/android/camera/Exif.java b/src/com/android/camera/Exif.java
index ee39d675e..c6ec6af50 100644
--- a/src/com/android/camera/Exif.java
+++ b/src/com/android/camera/Exif.java
@@ -20,32 +20,35 @@ import android.util.Log;
import com.android.gallery3d.exif.ExifInterface;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStream;
public class Exif {
private static final String TAG = "CameraExif";
- // Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
- public static int getOrientation(byte[] jpeg) {
- if (jpeg == null) {
- return 0;
- }
-
+ public static ExifInterface getExif(byte[] jpegData) {
ExifInterface exif = new ExifInterface();
- InputStream is = new ByteArrayInputStream(jpeg);
try {
- exif.readExif(is);
- Integer val = exif.getTagIntValue(ExifInterface.TAG_ORIENTATION);
- if (val == null) {
- return 0;
- } else {
- return ExifInterface.getRotationForOrientationValue(val.shortValue());
- }
+ exif.readExif(jpegData);
} catch (IOException e) {
- Log.w(TAG, "Failed to read EXIF orientation", e);
+ Log.w(TAG, "Failed to read EXIF data", e);
+ }
+ return exif;
+ }
+
+ // Returns the degrees in clockwise. Values are 0, 90, 180, or 270.
+ public static int getOrientation(ExifInterface exif) {
+ Integer val = exif.getTagIntValue(ExifInterface.TAG_ORIENTATION);
+ if (val == null) {
return 0;
+ } else {
+ return ExifInterface.getRotationForOrientationValue(val.shortValue());
}
}
+
+ public static int getOrientation(byte[] jpegData) {
+ if (jpegData == null) return 0;
+
+ ExifInterface exif = getExif(jpegData);
+ return getOrientation(exif);
+ }
}
diff --git a/src/com/android/camera/MediaSaveService.java b/src/com/android/camera/MediaSaveService.java
index 48fb629e9..b1f47df77 100644
--- a/src/com/android/camera/MediaSaveService.java
+++ b/src/com/android/camera/MediaSaveService.java
@@ -26,6 +26,8 @@ import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
+import com.android.gallery3d.exif.ExifInterface;
+
/*
* Service for saving images in the background thread.
*/
@@ -77,14 +79,14 @@ public class MediaSaveService extends Service {
// Runs in main thread
public void addImage(final byte[] data, String title, long date, Location loc,
- int width, int height, int orientation,
+ int width, int height, int orientation, ExifInterface exif,
OnMediaSavedListener l, ContentResolver resolver) {
if (isQueueFull()) {
Log.e(TAG, "Cannot add image when the queue is full");
return;
}
SaveTask t = new SaveTask(data, title, date, (loc == null) ? null : new Location(loc),
- width, height, orientation, resolver, l);
+ width, height, orientation, exif, resolver, l);
mTaskNumber++;
if (isQueueFull()) {
@@ -114,12 +116,13 @@ public class MediaSaveService extends Service {
private Location loc;
private int width, height;
private int orientation;
+ private ExifInterface exif;
private ContentResolver resolver;
private OnMediaSavedListener listener;
public SaveTask(byte[] data, String title, long date, Location loc,
- int width, int height, int orientation, ContentResolver resolver,
- OnMediaSavedListener listener) {
+ int width, int height, int orientation, ExifInterface exif,
+ ContentResolver resolver, OnMediaSavedListener listener) {
this.data = data;
this.title = title;
this.date = date;
@@ -127,6 +130,7 @@ public class MediaSaveService extends Service {
this.width = width;
this.height = height;
this.orientation = orientation;
+ this.exif = exif;
this.resolver = resolver;
this.listener = listener;
}
@@ -139,7 +143,7 @@ public class MediaSaveService extends Service {
@Override
protected Uri doInBackground(Void... v) {
return Storage.addImage(
- resolver, title, date, loc, orientation, data, width, height);
+ resolver, title, date, loc, orientation, exif, data, width, height);
}
@Override
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 037e0fdb3..ff2faf790 100644
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -21,6 +21,7 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
@@ -31,6 +32,10 @@ import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
import android.location.Location;
import android.media.CameraProfile;
import android.net.Uri;
@@ -56,6 +61,9 @@ import com.android.camera.ui.PopupManager;
import com.android.camera.ui.RotateTextToast;
import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;
+import com.android.gallery3d.exif.ExifInterface;
+import com.android.gallery3d.exif.ExifTag;
+import com.android.gallery3d.exif.Rational;
import com.android.gallery3d.filtershow.CropExtras;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.util.UsageStatistics;
@@ -77,7 +85,8 @@ public class PhotoModule
CameraPreference.OnPreferenceChangedListener,
ShutterButton.OnShutterButtonListener,
MediaSaveService.Listener,
- OnCountDownFinishedListener {
+ OnCountDownFinishedListener,
+ SensorEventListener {
private static final String TAG = "CAM_PhotoModule";
@@ -239,6 +248,12 @@ public class PhotoModule
CameraStartUpThread mCameraStartUpThread;
ConditionVariable mStartPreviewPrerequisiteReady = new ConditionVariable();
+ private SensorManager mSensorManager;
+ private float[] mGData = new float[3];
+ private float[] mMData = new float[3];
+ private float[] mR = new float[16];
+ private int mHeading = -1;
+
private MediaSaveService.OnMediaSavedListener mOnMediaSavedListener =
new MediaSaveService.OnMediaSavedListener() {
@Override
@@ -417,6 +432,8 @@ public class PhotoModule
initializeControlByIntent();
mQuickCapture = mActivity.getIntent().getBooleanExtra(EXTRA_QUICK_CAPTURE, false);
mLocationManager = new LocationManager(mActivity, mUI);
+ mSensorManager = (SensorManager)(mActivity.getSystemService(Context.SENSOR_SERVICE));
+
}
private void initializeControlByIntent() {
@@ -792,7 +809,8 @@ public class PhotoModule
if (!mIsImageCaptureIntent) {
// Calculate the width and the height of the jpeg.
Size s = mParameters.getPictureSize();
- int orientation = Exif.getOrientation(jpegData);
+ ExifInterface exif = Exif.getExif(jpegData);
+ int orientation = Exif.getOrientation(exif);
int width, height;
if ((mJpegRotation + orientation) % 180 == 0) {
width = s.width;
@@ -807,9 +825,20 @@ public class PhotoModule
Log.e(TAG, "Unbalanced name/data pair");
} else {
if (date == -1) date = mCaptureStartTime;
+ if (mHeading >= 0) {
+ // heading direction has been updated by the sensor.
+ ExifTag directionRefTag = exif.buildTag(
+ ExifInterface.TAG_GPS_IMG_DIRECTION_REF,
+ ExifInterface.GpsTrackRef.MAGNETIC_DIRECTION);
+ ExifTag directionTag = exif.buildTag(
+ ExifInterface.TAG_GPS_IMG_DIRECTION,
+ new Rational(mHeading, 1));
+ exif.setTag(directionRefTag);
+ exif.setTag(directionTag);
+ }
mActivity.getMediaSaveService().addImage(
jpegData, title, date, mLocation, width, height,
- orientation, mOnMediaSavedListener, mContentResolver);
+ orientation, exif, mOnMediaSavedListener, mContentResolver);
}
} else {
mJpegImageData = jpegData;
@@ -1091,7 +1120,8 @@ public class PhotoModule
Util.closeSilently(outputStream);
}
} else {
- int orientation = Exif.getOrientation(data);
+ ExifInterface exif = Exif.getExif(data);
+ int orientation = Exif.getOrientation(exif);
Bitmap bitmap = Util.makeBitmap(data, 50 * 1024);
bitmap = Util.rotate(bitmap, orientation);
mActivity.setResultEx(Activity.RESULT_OK,
@@ -1258,6 +1288,16 @@ public class PhotoModule
PopupManager.getInstance(mActivity).notifyShowPopup(null);
UsageStatistics.onContentViewChanged(
UsageStatistics.COMPONENT_CAMERA, "PhotoModule");
+
+ Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ if (gsensor != null) {
+ mSensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
+
+ Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
+ if (msensor != null) {
+ mSensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_NORMAL);
+ }
}
void waitCameraStartUpThread() {
@@ -1276,6 +1316,15 @@ public class PhotoModule
@Override
public void onPauseBeforeSuper() {
mPaused = true;
+ Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ if (gsensor != null) {
+ mSensorManager.unregisterListener(this, gsensor);
+ }
+
+ Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
+ if (msensor != null) {
+ mSensorManager.unregisterListener(this, msensor);
+ }
}
@Override
@@ -1975,4 +2024,33 @@ public class PhotoModule
s.setListener(this);
}
}
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ int type = event.sensor.getType();
+ float[] data;
+ if (type == Sensor.TYPE_ACCELEROMETER) {
+ data = mGData;
+ } else if (type == Sensor.TYPE_MAGNETIC_FIELD) {
+ data = mMData;
+ } else {
+ // we should not be here.
+ return;
+ }
+ for (int i = 0; i < 3 ; i++) {
+ data[i] = event.values[i];
+ }
+ float[] orientation = new float[3];
+ SensorManager.getRotationMatrix(mR, null, mGData, mMData);
+ SensorManager.getOrientation(mR, orientation);
+ mHeading = (int) (orientation[0] * 180f / Math.PI) % 360;
+ if (mHeading < 0) {
+ mHeading += 360;
+ }
+ Log.v(TAG, "heading:" + mHeading);
+ }
}
diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java
index 648fa7d87..ba995edef 100644
--- a/src/com/android/camera/Storage.java
+++ b/src/com/android/camera/Storage.java
@@ -30,6 +30,7 @@ import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import com.android.gallery3d.common.ApiHelper;
+import com.android.gallery3d.exif.ExifInterface;
import java.io.File;
import java.io.FileOutputStream;
@@ -49,7 +50,7 @@ public class Storage {
public static final long UNAVAILABLE = -1L;
public static final long PREPARING = -2L;
public static final long UNKNOWN_SIZE = -3L;
- public static final long LOW_STORAGE_THRESHOLD= 50000000;
+ public static final long LOW_STORAGE_THRESHOLD = 50000000;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private static void setImageSize(ContentValues values, int width, int height) {
@@ -77,11 +78,19 @@ public class Storage {
// Save the image and add it to media store.
public static Uri addImage(ContentResolver resolver, String title,
- long date, Location location, int orientation, byte[] jpeg,
- int width, int height) {
+ long date, Location location, int orientation, ExifInterface exif,
+ byte[] jpeg, int width, int height) {
// Save the image.
String path = generateFilepath(title);
- writeFile(path, jpeg);
+ if (exif != null) {
+ try {
+ exif.writeExif(jpeg, path);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to write data", e);
+ }
+ } else {
+ writeFile(path, jpeg);
+ }
return addImage(resolver, title, date, location, orientation,
jpeg.length, path, width, height);
}
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index 998bbf784..94c862502 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -58,6 +58,7 @@ import com.android.camera.ui.PopupManager;
import com.android.camera.ui.RotateTextToast;
import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;
+import com.android.gallery3d.exif.ExifInterface;
import com.android.gallery3d.util.AccessibilityUtils;
import com.android.gallery3d.util.UsageStatistics;
@@ -2213,11 +2214,12 @@ public class VideoModule implements CameraModule,
private void storeImage(final byte[] data, Location loc) {
long dateTaken = System.currentTimeMillis();
String title = Util.createJpegName(dateTaken);
- int orientation = Exif.getOrientation(data);
+ ExifInterface exif = Exif.getExif(data);
+ int orientation = Exif.getOrientation(exif);
Size s = mParameters.getPictureSize();
mActivity.getMediaSaveService().addImage(
- data, title, dateTaken, loc, s.width, s.height,
- orientation, mOnMediaSavedListener, mContentResolver);
+ data, title, dateTaken, loc, s.width, s.height, orientation,
+ exif, mOnMediaSavedListener, mContentResolver);
}
private boolean resetEffect() {