display photos in marker list

This commit is contained in:
Jimmy Shih
2013-08-07 18:38:00 -07:00
parent ba859b64e3
commit 8f35da9576
8 changed files with 302 additions and 187 deletions
+62 -34
View File
@@ -24,9 +24,9 @@ limitations under the License.
android:shrinkColumns="1"
android:stretchColumns="1"
style="@style/ListItem" >
<TableRow
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<!-- First row -->
<TableRow>
<!-- First column -->
<ImageView
android:contentDescription="@string/icon_track"
android:id="@+id/list_item_icon"
@@ -35,39 +35,67 @@ limitations under the License.
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_width="wrap_content" />
<TableLayout
<!-- Second column -->
<LinearLayout
android:baselineAligned="false"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:shrinkColumns="0"
android:stretchColumns="0" >
<TableRow>
<TextView
android:id="@+id/list_item_name"
android:layout_gravity="bottom"
android:layout_width="fill_parent"
android:singleLine="true"
style="@style/TextMedium" />
<TextView
android:id="@+id/list_item_date"
style="@style/ListItemDate" />
</TableRow>
<TableRow>
<!-- Need to match the style set in ListItemUtils.setListItem -->
<TextView
android:id="@+id/list_item_time_distance"
android:layout_gravity="bottom"
android:layout_width="fill_parent"
android:singleLine="true"
style="@style/TextSmall" />
<TextView
android:id="@+id/list_item_time"
style="@style/ListItemDate" />
</TableRow>
</TableLayout>
android:layout_width="match_parent" >
<LinearLayout
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_width="0dp" >
<TableLayout
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="0dp"
android:shrinkColumns="*"
android:stretchColumns="*" >
<TableRow>
<TextView
android:ellipsize="end"
android:id="@+id/list_item_name"
android:singleLine="true"
style="@style/TextMedium" />
</TableRow>
<TableRow>
<!-- Need to match the style set in ListItemUtils.setListItem -->
<TextView
android:ellipsize="end"
android:id="@+id/list_item_time_distance"
android:singleLine="true"
style="@style/TextSmall" />
</TableRow>
</TableLayout>
<ImageView
android:id="@+id/list_item_photo"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:layout_width="0dp"
android:scaleType="centerCrop" />
</LinearLayout>
<TableLayout
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="0dp"
android:shrinkColumns="*"
android:stretchColumns="*" >
<TableRow>
<TextView
android:id="@+id/list_item_date"
style="@style/ListItemDate" />
</TableRow>
<TableRow>
<TextView
android:id="@+id/list_item_time"
style="@style/ListItemDate" />
</TableRow>
</TableLayout>
</LinearLayout>
</TableRow>
<TableRow
android:layout_height="wrap_content"
android:layout_width="match_parent" >
<!-- Second row -->
<TableRow>
<TextView
android:id="@+id/list_item_description"
android:layout_column="1"
-1
View File
@@ -36,7 +36,6 @@ limitations under the License.
android:id="@+id/marker_detail_waypoint_description"
style="@style/TextLarge.WithTopMargin" />
<ImageView
android:adjustViewBounds="true"
android:id="@+id/marker_detail_waypoint_photo"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
@@ -23,14 +23,12 @@ import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteMarkerDialogFragment.DeleteMarkerCaller;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PhotoUtils;
import com.google.android.apps.mytracks.util.StatsUtils;
import com.google.android.maps.mytracks.R;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
@@ -41,8 +39,6 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.IOException;
/**
* An activity to display marker detail info.
*
@@ -73,7 +69,7 @@ public class MarkerDetailActivity extends AbstractMyTracksActivity implements De
finish();
return;
}
// Set waypoint, needed in onCreateOptionsMenu
waypoint = myTracksProviderUtils.getWaypoint(markerId);
if (waypoint == null) {
@@ -103,7 +99,7 @@ public class MarkerDetailActivity extends AbstractMyTracksActivity implements De
finish();
return;
}
name.setText(getString(R.string.generic_name_line, waypoint.getName()));
if (waypoint.getType() == WaypointType.WAYPOINT) {
waypointSection.setVisibility(View.VISIBLE);
@@ -120,7 +116,11 @@ public class MarkerDetailActivity extends AbstractMyTracksActivity implements De
imageView.setVisibility(View.GONE);
} else {
imageView.setVisibility(View.VISIBLE);
setImageVew(imageView, Uri.parse(photoUrl));
Display defaultDisplay = getWindowManager().getDefaultDisplay();
int displayWidth = defaultDisplay.getWidth();
int displayHeight = defaultDisplay.getHeight();
bitmap = PhotoUtils.setImageVew(
imageView, Uri.parse(photoUrl), displayWidth, displayHeight, true);
}
} else {
waypointSection.setVisibility(View.GONE);
@@ -190,107 +190,4 @@ public class MarkerDetailActivity extends AbstractMyTracksActivity implements De
}
});
}
/**
* Sets an image view.
*
* @param imageView the image view
* @param uri the image uri
*/
private void setImageVew(ImageView imageView, Uri uri) {
// Get the image dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(uri.getPath(), options);
// Set imageWidth and imageHeight based on image rotation
int rotation = getRotation(uri);
int imageWidth;
int imageHeight;
if (rotation == 0 || rotation == 180) {
imageWidth = options.outWidth;
imageHeight = options.outHeight;
} else {
imageWidth = options.outHeight;
imageHeight = options.outWidth;
}
// Get a scaled down version of the image
Display defaultDisplay = getWindowManager().getDefaultDisplay();
int displayWidth = defaultDisplay.getWidth();
int displayHeight = defaultDisplay.getHeight();
options.inJustDecodeBounds = false;
options.inSampleSize = getInSampleSize(imageWidth, imageHeight, displayWidth, displayHeight);
options.inPurgeable = true;
Bitmap scaledBitmap = BitmapFactory.decodeFile(uri.getPath(), options);
// Rotate the scaled down image
if (rotation == 0) {
bitmap = scaledBitmap;
} else {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(
scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
scaledBitmap.recycle();
}
imageView.setImageBitmap(bitmap);
}
/**
* Gets the image rotation
*
* @param uri the image uri
*/
private int getRotation(Uri uri) {
try {
ExifInterface exifInterface = new ExifInterface(uri.getPath());
switch (exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) {
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
} catch (IOException e) {
Log.e(TAG, "Unable to get photo orientation", e);
return 0;
}
}
/**
* Gets the in sample size.
*
* @param imageWidth the image width
* @param imageHeight the image height
* @param displayWidth the display width. Can be 0
* @param displayHeight the display height. Can be 0
*/
private int getInSampleSize(
int imageWidth, int imageHeight, int displayWidth, int displayHeight) {
int widthRatio = 1;
if (displayWidth != 0 && imageWidth > displayWidth) {
widthRatio = Math.round((float) imageWidth / (float) displayWidth);
}
int heightRatio = 1;
if (displayHeight != 0 && imageHeight > displayHeight) {
heightRatio = Math.round((float) imageHeight / (float) displayHeight);
}
/*
* Return the larger sample ratio so the image will not be larger than the
* displayWidth and displayHeight.
*/
return Math.max(widthRatio, heightRatio);
}
}
@@ -63,7 +63,7 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
private static final String[] PROJECTION = new String[] { WaypointsColumns._ID,
WaypointsColumns.NAME, WaypointsColumns.DESCRIPTION, WaypointsColumns.CATEGORY,
WaypointsColumns.TYPE, WaypointsColumns.TIME };
WaypointsColumns.TYPE, WaypointsColumns.TIME, WaypointsColumns.PHOTOURL };
// Callback when an item is selected in the contextual action mode
private ContextualActionModeCallback
@@ -173,19 +173,25 @@ public class MarkerListActivity extends AbstractMyTracksActivity implements Dele
public void bindView(View view, Context context, Cursor cursor) {
int typeIndex = cursor.getColumnIndex(WaypointsColumns.TYPE);
int nameIndex = cursor.getColumnIndex(WaypointsColumns.NAME);
int categoryIndex = cursor.getColumnIndex(WaypointsColumns.CATEGORY);
int photoUrlIndex = cursor.getColumnIndex(WaypointsColumns.PHOTOURL);
int timeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.TIME);
int categoryIndex = cursor.getColumnIndex(WaypointsColumns.CATEGORY);
int descriptionIndex = cursor.getColumnIndex(WaypointsColumns.DESCRIPTION);
boolean statistics = WaypointType.values()[cursor.getInt(typeIndex)]
== WaypointType.STATISTICS;
int iconId = statistics ? R.drawable.ic_marker_yellow_pushpin
: R.drawable.ic_marker_blue_pushpin;
String name = cursor.getString(nameIndex);
String sharedOwner = track.getSharedOwner();
String photoUrl = cursor.getString(photoUrlIndex);
long time = cursor.getLong(timeIndex);
String category = statistics ? null : cursor.getString(categoryIndex);
String description = statistics ? null : cursor.getString(descriptionIndex);
ListItemUtils.setListItem(MarkerListActivity.this, view, false, true, iconId,
R.string.icon_marker, cursor.getString(nameIndex), category, null, null,
cursor.getLong(timeIndex), description, track.getSharedOwner());
R.string.icon_marker, name, sharedOwner, null, null, photoUrl, time, category,
description);
}
};
listView.setAdapter(resourceCursorAdapter);
@@ -83,12 +83,14 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
private static final String ICON_ID_FIELD = "icon";
private static final String ICON_CONTENT_DESCRIPTION_ID_FIELD = "iconContentDescription";
private static final String NAME_FIELD = "name";
private static final String CATEGORY_FIELD = "category";
private static final String SHARED_OWNER_FIELD = "sharedOwner";
private static final String TOTAL_TIME_FIELD = "totalTime";
private static final String TOTAL_DISTANCE_FIELD = "totalDistance";
private static final String PHOTO_URL_FIELD = "photoUrl";
private static final String START_TIME_FIELD = "startTime";
private static final String CATEGORY_FIELD = "category";
private static final String DESCRIPTION_FIELD = "description";
private static final String SHARED_OWNER_FIELD = "sharedOwner";
private static final String TRACK_ID_FIELD = "trackId";
private static final String MARKER_ID_FIELD = "markerId";
@@ -228,15 +230,17 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
int iconId = (Integer) resultMap.get(ICON_ID_FIELD);
int iconContentDescriptionId = (Integer) resultMap.get(ICON_CONTENT_DESCRIPTION_ID_FIELD);
String name = (String) resultMap.get(NAME_FIELD);
String category = (String) resultMap.get(CATEGORY_FIELD);
String sharedOwner = (String) resultMap.get(SHARED_OWNER_FIELD);
String totalTime = (String) resultMap.get(TOTAL_TIME_FIELD);
String totalDistance = (String) resultMap.get(TOTAL_DISTANCE_FIELD);
String photoUrl = (String) resultMap.get(PHOTO_URL_FIELD);
Long startTime = (Long) resultMap.get(START_TIME_FIELD);
String category = (String) resultMap.get(CATEGORY_FIELD);
String description = (String) resultMap.get(DESCRIPTION_FIELD);
String sharedOwner = (String) resultMap.get(SHARED_OWNER_FIELD);
ListItemUtils.setListItem(SearchListActivity.this, view, isRecording, isPaused, iconId,
iconContentDescriptionId, name, category, totalTime, totalDistance, startTime,
description, sharedOwner);
iconContentDescriptionId, name, sharedOwner, totalTime, totalDistance, photoUrl,
startTime, category, description);
return view;
}
};
@@ -487,14 +491,15 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
statistics ? R.drawable.ic_marker_yellow_pushpin : R.drawable.ic_marker_blue_pushpin);
resultMap.put(ICON_CONTENT_DESCRIPTION_ID_FIELD, R.string.icon_marker);
resultMap.put(NAME_FIELD, waypoint.getName());
resultMap.put(CATEGORY_FIELD, statistics ? null : waypoint.getCategory());
resultMap.put(SHARED_OWNER_FIELD, sharedOwner);
// Display the marker's track name in the total time field
resultMap.put(TOTAL_TIME_FIELD, trackName == null ? null
: getString(R.string.search_list_marker_track_location, trackName));
resultMap.put(TOTAL_DISTANCE_FIELD, null);
resultMap.put(PHOTO_URL_FIELD, waypoint.getPhotoUrl());
resultMap.put(START_TIME_FIELD, waypoint.getLocation().getTime());
resultMap.put(CATEGORY_FIELD, statistics ? null : waypoint.getCategory());
resultMap.put(DESCRIPTION_FIELD, statistics ? null : waypoint.getDescription());
resultMap.put(SHARED_OWNER_FIELD, sharedOwner);
resultMap.put(TRACK_ID_FIELD, waypoint.getTrackId());
resultMap.put(MARKER_ID_FIELD, waypoint.getId());
}
@@ -515,13 +520,14 @@ public class SearchListActivity extends AbstractSendToGoogleActivity implements
resultMap.put(ICON_ID_FIELD, TrackIconUtils.getIconDrawable(icon));
resultMap.put(ICON_CONTENT_DESCRIPTION_ID_FIELD, R.string.icon_track);
resultMap.put(NAME_FIELD, track.getName());
resultMap.put(CATEGORY_FIELD, category);
resultMap.put(SHARED_OWNER_FIELD, track.getSharedOwner());
resultMap.put(TOTAL_TIME_FIELD, StringUtils.formatElapsedTime(tripStatitics.getTotalTime()));
resultMap.put(TOTAL_DISTANCE_FIELD,
StringUtils.formatDistance(this, tripStatitics.getTotalDistance(), metricUnits));
resultMap.put(PHOTO_URL_FIELD, null);
resultMap.put(START_TIME_FIELD, tripStatitics.getStartTime());
resultMap.put(CATEGORY_FIELD, category);
resultMap.put(DESCRIPTION_FIELD, track.getDescription());
resultMap.put(SHARED_OWNER_FIELD, track.getSharedOwner());
resultMap.put(TRACK_ID_FIELD, track.getId());
resultMap.put(MARKER_ID_FIELD, null);
}
@@ -361,28 +361,28 @@ public class TrackListActivity extends AbstractSendToGoogleActivity
int idIndex = cursor.getColumnIndex(TracksColumns._ID);
int iconIndex = cursor.getColumnIndex(TracksColumns.ICON);
int nameIndex = cursor.getColumnIndex(TracksColumns.NAME);
int categoryIndex = cursor.getColumnIndex(TracksColumns.CATEGORY);
int sharedOwnerIndex = cursor.getColumnIndex(TracksColumns.SHAREDOWNER);
int totalTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALTIME);
int totalDistanceIndex = cursor.getColumnIndexOrThrow(TracksColumns.TOTALDISTANCE);
int startTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
int startTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.STARTTIME);
int categoryIndex = cursor.getColumnIndex(TracksColumns.CATEGORY);
int descriptionIndex = cursor.getColumnIndex(TracksColumns.DESCRIPTION);
int sharedOwnerIndex = cursor.getColumnIndex(TracksColumns.SHAREDOWNER);
boolean isRecording = cursor.getLong(idIndex) == recordingTrackId;
String icon = cursor.getString(iconIndex);
int iconId = TrackIconUtils.getIconDrawable(icon);
String name = cursor.getString(nameIndex);
String category = icon != null && !icon.equals("") ? null : cursor.getString(categoryIndex);
String sharedOwner = cursor.getString(sharedOwnerIndex);
String totalTime = StringUtils.formatElapsedTime(cursor.getLong(totalTimeIndex));
String totalDistance = StringUtils.formatDistance(
TrackListActivity.this, cursor.getDouble(totalDistanceIndex), metricUnits);
long startTime = cursor.getLong(startTimeIndex);
long startTime = cursor.getLong(startTimeIndex);
String category = icon != null && !icon.equals("") ? null : cursor.getString(categoryIndex);
String description = cursor.getString(descriptionIndex);
String sharedOwner = cursor.getString(sharedOwnerIndex);
ListItemUtils.setListItem(TrackListActivity.this, view, isRecording, recordingTrackPaused,
iconId, R.string.icon_track, name, category, totalTime, totalDistance, startTime,
description, sharedOwner);
iconId, R.string.icon_track, name, sharedOwner, totalTime, totalDistance, null,
startTime, category, description);
}
};
listView.setAdapter(sectionResourceCursorAdapter);
@@ -18,8 +18,11 @@ package com.google.android.apps.mytracks.util;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.text.format.DateUtils;
import android.view.Display;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
@@ -38,23 +41,25 @@ public class ListItemUtils {
/**
* Sets a list item.
*
* @param context the context
* @param activity the activity
* @param view the list item view
* @param isRecording true if recording
* @param isPaused true if paused
* @param name the name value
* @param iconId the icon id
* @param iconContentDescriptionId the icon content description id
* @param category the category value
* @param name the name value
* @param sharedOwner if shared with me track, the owner, else null
* @param totalTime the total time value
* @param totalDistance the total distance value
* @param photoUrl the photo url
* @param startTime the start time value
* @param category the category value
* @param description the description value
* @param sharedOwner if shared with me track, the owner, else null
*/
public static void setListItem(Context context, View view, boolean isRecording, boolean isPaused,
int iconId, int iconContentDescriptionId, String name, String category, String totalTime,
String totalDistance, long startTime, String description, String sharedOwner) {
public static void setListItem(Activity activity, View view, boolean isRecording,
boolean isPaused, int iconId, int iconContentDescriptionId, String name, String sharedOwner,
String totalTime, String totalDistance, String photoUrl, long startTime, String category,
String description) {
if (isRecording) {
iconId = isPaused ? R.drawable.ic_track_paused : R.drawable.ic_track_recording;
@@ -64,32 +69,47 @@ public class ListItemUtils {
ImageView iconImageView = (ImageView) view.findViewById(R.id.list_item_icon);
iconImageView.setImageResource(iconId);
iconImageView.setContentDescription(context.getString(iconContentDescriptionId));
iconImageView.setContentDescription(activity.getString(iconContentDescriptionId));
// Set name
TextView nameTextView = (TextView) view.findViewById(R.id.list_item_name);
nameTextView.setText(name);
// Set sharedOwner/totalTime/totalDistance
TextView timeDistanceTextView = (TextView) view.findViewById(R.id.list_item_time_distance);
if (isRecording) {
timeDistanceTextView.setTextColor(context.getResources()
timeDistanceTextView.setTextColor(activity.getResources()
.getColor(isPaused ? android.R.color.white : R.color.recording_text));
} else {
// Need to match the style set in list_item.xml
timeDistanceTextView.setTextAppearance(context, R.style.TextSmall);
timeDistanceTextView.setTextAppearance(activity, R.style.TextSmall);
}
setTextView(timeDistanceTextView,
getTimeDistance(context, isRecording, isPaused, sharedOwner, totalTime, totalDistance),
View.INVISIBLE);
getTimeDistance(activity, isRecording, isPaused, sharedOwner, totalTime, totalDistance));
String[] startTimeDisplay = getStartTime(isRecording, context, startTime);
// Set photoUrl
ImageView photo = (ImageView) view.findViewById(R.id.list_item_photo);
if (photoUrl == null || photoUrl.equals("")) {
photo.setVisibility(View.GONE);
} else {
photo.setVisibility(View.VISIBLE);
Display defaultDisplay = activity.getWindowManager().getDefaultDisplay();
// Set the initial width to 35% of the display width
int width = (int) (defaultDisplay.getWidth() * .35);
PhotoUtils.setImageVew(photo, Uri.parse(photoUrl), width, 0, false);
}
// Set date/time
String[] startTimeDisplay = getStartTime(isRecording, activity, startTime);
TextView dateTextView = (TextView) view.findViewById(R.id.list_item_date);
setTextView(dateTextView, startTimeDisplay[0], View.GONE);
setTextView(dateTextView, startTimeDisplay[0]);
TextView timeTextView = (TextView) view.findViewById(R.id.list_item_time);
setTextView(timeTextView, startTimeDisplay[1], View.GONE);
setTextView(timeTextView, startTimeDisplay[1]);
// Set category/description
TextView descriptionTextView = (TextView) view.findViewById(R.id.list_item_description);
setTextView(descriptionTextView, getDescription(isRecording, category, description), View.GONE);
setTextView(descriptionTextView, getDescription(isRecording, category, description));
}
/**
@@ -194,11 +214,10 @@ public class ListItemUtils {
*
* @param textView the text view
* @param value the value for the text view
* @param visibility visibility when value is not available
*/
private static void setTextView(TextView textView, String value, int visibility) {
private static void setTextView(TextView textView, String value) {
if (value == null || value.length() == 0) {
textView.setVisibility(visibility);
textView.setVisibility(View.GONE);
} else {
textView.setVisibility(View.VISIBLE);
textView.setText(value);
@@ -0,0 +1,160 @@
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.util.Log;
import android.widget.ImageView;
import java.io.IOException;
/**
* Utilities for photos.
*
* @author Jimmy Shih
*/
public class PhotoUtils {
private static final String TAG = PhotoUtils.class.getSimpleName();
private PhotoUtils() {}
/**
* Sets an image view.
*
* @param imageView the image view
* @param uri the image uri
* @param displayWidth the display width
* @param displayHeight the display height
* @param fitWithIn true to fit within the display area. False to crop and fill
* the display area.
*/
public static Bitmap setImageVew(
ImageView imageView, Uri uri, int displayWidth, int displayHeight, boolean fitWithIn) {
// Get the image dimensions
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(uri.getPath(), options);
// Set targetWidth and targetHeight
int targetWidth = displayWidth;
int targetHeight = displayHeight;
if (targetHeight == 0) {
targetHeight = (int) (targetWidth * ((float) options.outHeight / (float) options.outWidth));
imageView.getLayoutParams().height = targetHeight;
}
// Set imageWidth and imageHeight based on image rotation
int rotation = getRotation(uri);
int imageWidth;
int imageHeight;
if (rotation == 0 || rotation == 180) {
imageWidth = options.outWidth;
imageHeight = options.outHeight;
} else {
imageWidth = options.outHeight;
imageHeight = options.outWidth;
}
// Get a scaled down version of the image
options.inJustDecodeBounds = false;
options.inSampleSize = getInSampleSize(
imageWidth, imageHeight, targetWidth, targetHeight, fitWithIn);
options.inPurgeable = true;
Bitmap scaledBitmap = BitmapFactory.decodeFile(uri.getPath(), options);
// Get the final bitmap after rotating the scaled down image
Bitmap bitmap;
if (rotation == 0) {
bitmap = scaledBitmap;
} else {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(
scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
scaledBitmap.recycle();
}
imageView.setImageBitmap(bitmap);
return bitmap;
}
/**
* Gets the image rotation
*
* @param uri the image uri
*/
private static int getRotation(Uri uri) {
try {
ExifInterface exifInterface = new ExifInterface(uri.getPath());
switch (exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) {
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
} catch (IOException e) {
Log.e(TAG, "Unable to get photo orientation", e);
return 0;
}
}
/**
* Gets the in sample size.
*
* @param imageWidth the image width
* @param imageHeight the image height
* @param targetWidth the target width
* @param targetHeight the target height
* @param fitWithin true to fit within the target area. False to crop and fill
* all target area.
*/
private static int getInSampleSize(
int imageWidth, int imageHeight, int targetWidth, int targetHeight, boolean fitWithin) {
float widthRatio = 1;
if (imageWidth > targetWidth) {
widthRatio = (float) imageWidth / (float) targetWidth;
}
float heightRatio = 1;
if (imageHeight > targetHeight) {
heightRatio = (float) imageHeight / (float) targetHeight;
}
/*
* To fit within the target area, return the larger sample ratio so the
* image will not be larger than the target dimensions. To crop and fill the
* target area, return the smaller sample ratio so the image will be greater
* than the target dimensions. Use Math.floor to not under sample.
*/
return (int) Math.floor(
fitWithin ? Math.max(widthRatio, heightRatio) : Math.min(widthRatio, heightRatio));
}
}