From fae11a165e344a38811770c7d348eda214683edc Mon Sep 17 00:00:00 2001 From: Sascha Haeberling Date: Thu, 15 Aug 2013 14:29:49 -0700 Subject: [PATCH] Implent show-on-map functionality. Also make sure the show-on-map item is only shown for items with coordinates. and add the coordinate to the details view. Bug: 10346208 Bug: 10330505 Change-Id: Idaeec207bcc0e7311fa3b651868515ccea81d083 --- src/com/android/camera/CameraActivity.java | 21 ++++++---- src/com/android/camera/data/CameraPreviewData.java | 2 +- src/com/android/camera/data/LocalData.java | 3 +- src/com/android/camera/data/LocalMediaData.java | 46 ++++++++++++++++------ src/com/android/camera/data/SimpleViewData.java | 7 +++- src/com/android/camera/ui/FilmStripView.java | 9 ++++- src/com/android/camera/util/CameraUtil.java | 41 +++++++++++++++++-- 7 files changed, 102 insertions(+), 27 deletions(-) diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index 98ea363eb..57863b320 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -215,8 +215,7 @@ public class CameraActivity extends Activity hidePanoStitchingProgress(); return; } - int type = currentData.getLocalDataType(dataID); - updateActionBarMenu(type); + updateActionBarMenu(dataID); Uri contentUri = currentData.getContentUri(); if (contentUri == null) { @@ -249,9 +248,12 @@ public class CameraActivity extends Activity /** * According to the data type, make the menu items for supported operations * visible. - * @param type : the data type for the current local data. + * @param dataID the data ID of the current item. */ - private void updateActionBarMenu(int type) { + private void updateActionBarMenu(int dataID) { + LocalData currentData = mDataAdapter.getLocalData(dataID); + int type = currentData.getLocalDataType(); + if (mActionBarMenu == null) { return; } @@ -290,12 +292,14 @@ public class CameraActivity extends Activity (supported & SUPPORT_MUTE) != 0); setMenuItemVisible(mActionBarMenu, R.id.action_setas, (supported & SUPPORT_SETAS) != 0); - setMenuItemVisible(mActionBarMenu, R.id.action_show_on_map, - (supported & SUPPORT_SHOW_ON_MAP) != 0); setMenuItemVisible(mActionBarMenu, R.id.action_edit, (supported & SUPPORT_EDIT) != 0); setMenuItemVisible(mActionBarMenu, R.id.action_details, (supported & SUPPORT_INFO) != 0); + + boolean itemHasLocation = currentData.getLatLong() != null; + setMenuItemVisible(mActionBarMenu, R.id.action_show_on_map, + itemHasLocation && (supported & SUPPORT_SHOW_ON_MAP) != 0); } private void setMenuItemVisible(Menu menu, int itemId, boolean visible) { @@ -461,7 +465,10 @@ public class CameraActivity extends Activity }).execute(); return true; case R.id.action_show_on_map: - // TODO: add the functionality. + double[] latLong = localData.getLatLong(); + if (latLong != null) { + CameraUtil.showOnMap(this, latLong); + } return true; default: return super.onOptionsItemSelected(item); diff --git a/src/com/android/camera/data/CameraPreviewData.java b/src/com/android/camera/data/CameraPreviewData.java index 3a4510541..f6127e46f 100644 --- a/src/com/android/camera/data/CameraPreviewData.java +++ b/src/com/android/camera/data/CameraPreviewData.java @@ -45,7 +45,7 @@ public class CameraPreviewData extends SimpleViewData { } @Override - public int getLocalDataType(int dataID) { + public int getLocalDataType() { return LOCAL_CAMERA_PREVIEW; } diff --git a/src/com/android/camera/data/LocalData.java b/src/com/android/camera/data/LocalData.java index 61714e243..2b617d7e1 100644 --- a/src/com/android/camera/data/LocalData.java +++ b/src/com/android/camera/data/LocalData.java @@ -109,12 +109,11 @@ public interface LocalData extends FilmStripView.ImageData { /** * Returns the type of the local data defined by {@link LocalData}. * - * @param dataID The ID of the data. * @return The local data type. Could be one of the following: * {@code LOCAL_CAMERA_PREVIEW}, {@code LOCAL_VIEW}, {@code LOCAL_IMAGE}, * {@code LOCAL_VIDEO}, and {@code LOCAL_PHOTO_SPHERE}, */ - int getLocalDataType(int dataID); + int getLocalDataType(); /** * Refresh the data content. diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java index e55274f06..131c7e7db 100644 --- a/src/com/android/camera/data/LocalMediaData.java +++ b/src/com/android/camera/data/LocalMediaData.java @@ -61,6 +61,8 @@ public abstract class LocalMediaData implements LocalData { protected int width; protected int height; protected long sizeInBytes; + protected double latitude; + protected double longitude; /** The panorama metadata information of this media data. */ protected PhotoSphereHelper.PanoramaMetadata mPanoramaMetadata; @@ -192,6 +194,16 @@ public abstract class LocalMediaData implements LocalData { } } + @Override + public double[] getLatLong() { + if (latitude == 0 && longitude == 0) { + return null; + } + return new double[] { + latitude, longitude + }; + } + protected boolean isUsing() { synchronized (mUsing) { return mUsing; @@ -217,6 +229,8 @@ public abstract class LocalMediaData implements LocalData { public static final int COL_WIDTH = 7; public static final int COL_HEIGHT = 8; public static final int COL_SIZE = 9; + public static final int COL_LATITUDE = 10; + public static final int COL_LONGITUDE = 11; static final Uri CONTENT_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; @@ -226,16 +240,18 @@ public abstract class LocalMediaData implements LocalData { * These values should be kept in sync with column IDs (COL_*) above. */ static final String[] QUERY_PROJECTION = { - MediaStore.Images.ImageColumns._ID, // 0, int - MediaStore.Images.ImageColumns.TITLE, // 1, string - MediaStore.Images.ImageColumns.MIME_TYPE, // 2, string - MediaStore.Images.ImageColumns.DATE_TAKEN, // 3, int - MediaStore.Images.ImageColumns.DATE_MODIFIED, // 4, int - MediaStore.Images.ImageColumns.DATA, // 5, string - MediaStore.Images.ImageColumns.ORIENTATION, // 6, int, 0, 90, 180, 270 - MediaStore.Images.ImageColumns.WIDTH, // 7, int - MediaStore.Images.ImageColumns.HEIGHT, // 8, int - MediaStore.Images.ImageColumns.SIZE, // 9, long + MediaStore.Images.ImageColumns._ID, // 0, int + MediaStore.Images.ImageColumns.TITLE, // 1, string + MediaStore.Images.ImageColumns.MIME_TYPE, // 2, string + MediaStore.Images.ImageColumns.DATE_TAKEN, // 3, int + MediaStore.Images.ImageColumns.DATE_MODIFIED, // 4, int + MediaStore.Images.ImageColumns.DATA, // 5, string + MediaStore.Images.ImageColumns.ORIENTATION, // 6, int, 0, 90, 180, 270 + MediaStore.Images.ImageColumns.WIDTH, // 7, int + MediaStore.Images.ImageColumns.HEIGHT, // 8, int + MediaStore.Images.ImageColumns.SIZE, // 9, long + MediaStore.Images.ImageColumns.LATITUDE, // 10, double + MediaStore.Images.ImageColumns.LONGITUDE // 11, double }; private static final int mSupportedUIActions = @@ -286,6 +302,8 @@ public abstract class LocalMediaData implements LocalData { d.height = b; } d.sizeInBytes = c.getLong(COL_SIZE); + d.latitude = c.getDouble(COL_LATITUDE); + d.longitude = c.getDouble(COL_LONGITUDE); return d; } @@ -338,11 +356,15 @@ public abstract class LocalMediaData implements LocalData { mediaDetails.addDetail(MediaDetails.INDEX_SIZE, sizeInBytes); MediaDetails.extractExifInfo(mediaDetails, path); + + if (latitude != 0 && longitude != 0) { + mediaDetails.addDetail(MediaDetails.INDEX_LOCATION, latitude + ", " + longitude); + } return mediaDetails; } @Override - public int getLocalDataType(int dataID) { + public int getLocalDataType() { if (mPanoramaMetadata != null && mPanoramaMetadata.mUsePanoramaViewer) { return LOCAL_PHOTO_SPHERE; } @@ -535,7 +557,7 @@ public abstract class LocalMediaData implements LocalData { } @Override - public int getLocalDataType(int dataID) { + public int getLocalDataType() { return LOCAL_VIDEO; } diff --git a/src/com/android/camera/data/SimpleViewData.java b/src/com/android/camera/data/SimpleViewData.java index 8801599bb..59d5f2cd5 100644 --- a/src/com/android/camera/data/SimpleViewData.java +++ b/src/com/android/camera/data/SimpleViewData.java @@ -86,7 +86,7 @@ public class SimpleViewData implements LocalData { } @Override - public int getLocalDataType(int dataID) { + public int getLocalDataType() { return LOCAL_VIEW; } @@ -150,4 +150,9 @@ public class SimpleViewData implements LocalData { public MediaDetails getMediaDetails(Context context) { return null; } + + @Override + public double[] getLatLong() { + return null; + } } diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index dd5c29eb9..5e6bf699c 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -131,7 +131,6 @@ public class FilmStripView extends ViewGroup { */ public int getWidth(); - /** * Returns the width of the image. The final layout of the view returned * by {@link DataAdapter#getView(android.content.Context, int)} will @@ -145,6 +144,14 @@ public class FilmStripView extends ViewGroup { public int getViewType(); /** + * Returns the coordinates of this item. + * + * @return A 2-element array containing {latitude, longitude}, or null, + * if no position is known for this item. + */ + public double[] getLatLong(); + + /** * Checks if the UI action is supported. * * @param action The UI actions to check. diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java index a5d416160..c5dc71af3 100644 --- a/src/com/android/camera/util/CameraUtil.java +++ b/src/com/android/camera/util/CameraUtil.java @@ -22,6 +22,7 @@ import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; +import java.util.Locale; import java.util.StringTokenizer; import android.annotation.TargetApi; @@ -29,6 +30,7 @@ import android.app.Activity; import android.app.AlertDialog; import android.app.admin.DevicePolicyManager; import android.content.ActivityNotFoundException; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; @@ -105,9 +107,13 @@ public class CameraUtil { public static final String SCENE_MODE_HDR = "hdr"; public static final String TRUE = "true"; public static final String FALSE = "false"; - - /** Has to be in sync with the receiving MovieActivity. */ - public static final String KEY_TREAT_UP_AS_BACK = "treat-up-as-back"; + + // Fields for the show-on-maps-functionality + private static final String MAPS_PACKAGE_NAME = "com.google.android.apps.maps"; + private static final String MAPS_CLASS_NAME = "com.google.android.maps.MapsActivity"; + + /** Has to be in sync with the receiving MovieActivity. */ + public static final String KEY_TREAT_UP_AS_BACK = "treat-up-as-back"; public static boolean isSupported(String value, List supported) { return supported == null ? false : supported.indexOf(value) >= 0; @@ -832,4 +838,33 @@ public class CameraUtil { Toast.LENGTH_SHORT).show(); } } + + /** + * Starts GMM with the given location shown. If this fails, and GMM could + * not be found, we use a geo intent as a fallback. + * + * @param context the Android context to use for starting the activities. + * @param latLong a 2-element array containing {latitude/longitude}. + */ + public static void showOnMap(Context context, double[] latLong) { + try { + // We don't use "geo:latitude,longitude" because it only centers + // the MapView to the specified location, but we need a marker + // for further operations (routing to/from). + // The q=(lat, lng) syntax is suggested by geo-team. + String uri = String.format(Locale.ENGLISH, "http://maps.google.com/maps?f=q&q=(%f,%f)", + latLong[0], latLong[1]); + ComponentName compName = new ComponentName(MAPS_PACKAGE_NAME, + MAPS_CLASS_NAME); + Intent mapsIntent = new Intent(Intent.ACTION_VIEW, + Uri.parse(uri)).setComponent(compName); + context.startActivity(mapsIntent); + } catch (ActivityNotFoundException e) { + // Use the "geo intent" if no GMM is installed + Log.e(TAG, "GMM activity not found!", e); + String url = String.format(Locale.ENGLISH, "geo:%f,%f", latLong[0], latLong[1]); + Intent mapsIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + context.startActivity(mapsIntent); + } + } } -- 2.11.0