blob: 61e93826acc6a456d5eb36833260d5f788db8e37 [file] [log] [blame]
/*
* Copyright (C) 2011 Google Inc.
* Licensed to The Android Open Source Project.
*
* 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.android.ex.photo;
import android.app.Activity;
import android.content.ContentProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import com.android.ex.photo.fragments.PhotoViewFragment;
/**
* Build intents to start app activities
*/
public class Intents {
// Intent extras
public static final String EXTRA_PHOTO_INDEX = "photo_index";
public static final String EXTRA_INITIAL_PHOTO_URI = "initial_photo_uri";
public static final String EXTRA_PHOTOS_URI = "photos_uri";
public static final String EXTRA_RESOLVED_PHOTO_URI = "resolved_photo_uri";
public static final String EXTRA_PROJECTION = "projection";
public static final String EXTRA_THUMBNAIL_URI = "thumbnail_uri";
public static final String EXTRA_CONTENT_DESCRIPTION = "content_description";
public static final String EXTRA_MAX_INITIAL_SCALE = "max_scale";
public static final String EXTRA_WATCH_NETWORK = "watch_network";
public static final String EXTRA_ENABLE_TIMER_LIGHTS_OUT = "enable_timer_lights_out";
// Parameters affecting the intro/exit animation
public static final String EXTRA_SCALE_UP_ANIMATION = "scale_up_animation";
public static final String EXTRA_ANIMATION_START_X = "start_x_extra";
public static final String EXTRA_ANIMATION_START_Y = "start_y_extra";
public static final String EXTRA_ANIMATION_START_WIDTH = "start_width_extra";
public static final String EXTRA_ANIMATION_START_HEIGHT = "start_height_extra";
// Parameters affecting the display and features
public static final String EXTRA_ACTION_BAR_HIDDEN_INITIALLY = "action_bar_hidden_initially";
public static final String EXTRA_DISPLAY_THUMBS_FULLSCREEN = "display_thumbs_fullscreen";
/**
* Gets a photo view intent builder to display the photos from phone activity.
*
* @param context The context
* @return The intent builder
*/
public static PhotoViewIntentBuilder newPhotoViewActivityIntentBuilder(Context context) {
return new PhotoViewIntentBuilder(context, PhotoViewActivity.class);
}
/**
* Gets a photo view intent builder to display the photo view fragment
*
* @param context The context
* @return The intent builder
*/
public static PhotoViewIntentBuilder newPhotoViewFragmentIntentBuilder(Context context) {
return newPhotoViewFragmentIntentBuilder(context, PhotoViewFragment.class);
}
/**
* Gets a photo view intent builder to display the photo view fragment with a custom fragment
* subclass.
*
* @param context The context
* @param clazz Subclass of PhotoViewFragment to use
* @return The intent builder
*/
public static PhotoViewIntentBuilder newPhotoViewFragmentIntentBuilder(Context context,
Class<? extends PhotoViewFragment> clazz) {
return new PhotoViewIntentBuilder(context, clazz);
}
/** Gets a new photo view intent builder */
public static PhotoViewIntentBuilder newPhotoViewIntentBuilder(
Context context, Class<? extends Activity> cls) {
return new PhotoViewIntentBuilder(context, cls);
}
/** Gets a new photo view intent builder */
public static PhotoViewIntentBuilder newPhotoViewIntentBuilder(
Context context, String activityName) {
return new PhotoViewIntentBuilder(context, activityName);
}
/** Builder to create a photo view intent */
public static class PhotoViewIntentBuilder {
private final Intent mIntent;
/** The index of the photo to show */
private Integer mPhotoIndex;
/** The URI of the initial photo to show */
private String mInitialPhotoUri;
/** The URI of the initial thumbnail to show */
private String mInitialThumbnailUri;
/** The URI of the group of photos to display */
private String mPhotosUri;
/** The URL of the photo to display */
private String mResolvedPhotoUri;
/** The projection for the query to use; optional */
private String[] mProjection;
/** The URI of a thumbnail of the photo to display */
private String mThumbnailUri;
/** The content Description for the photo to show */
private String mContentDescription;
/** The maximum scale to display images at before */
private Float mMaxInitialScale;
/** True if lights out should automatically be invoked on a timer basis */
private boolean mEnableTimerLightsOut;
/**
* True if the PhotoViewFragments should watch for network changes to restart their loaders
*/
private boolean mWatchNetwork;
/** true we want to run the image scale animation */
private boolean mScaleAnimation;
/** The parameters for performing the scale up/scale down animations
* upon enter and exit. StartX and StartY represent the screen coordinates
* of the upper left corner of the start rectangle, startWidth and startHeight
* represent the width and height of the start rectangle.
*/
private int mStartX;
private int mStartY;
private int mStartWidth;
private int mStartHeight;
private boolean mActionBarHiddenInitially;
private boolean mDisplayFullScreenThumbs;
private PhotoViewIntentBuilder(Context context, Class<?> cls) {
mIntent = new Intent(context, cls);
initialize();
}
private PhotoViewIntentBuilder(Context context, String activityName) {
mIntent = new Intent();
mIntent.setClassName(context, activityName);
initialize();
}
private void initialize() {
mScaleAnimation = false;
mActionBarHiddenInitially = false;
mDisplayFullScreenThumbs = false;
mEnableTimerLightsOut = true;
}
/** Sets auto lights out */
public PhotoViewIntentBuilder setEnableTimerLightsOut(boolean enable) {
mEnableTimerLightsOut = enable;
return this;
}
/** Sets the photo index */
public PhotoViewIntentBuilder setPhotoIndex(Integer photoIndex) {
mPhotoIndex = photoIndex;
return this;
}
/** Sets the initial photo URI */
public PhotoViewIntentBuilder setInitialPhotoUri(String initialPhotoUri) {
mInitialPhotoUri = initialPhotoUri;
return this;
}
/** Sets the photos URI */
public PhotoViewIntentBuilder setPhotosUri(String photosUri) {
mPhotosUri = photosUri;
return this;
}
/** Sets the query projection */
public PhotoViewIntentBuilder setProjection(String[] projection) {
mProjection = projection;
return this;
}
/** Sets the resolved photo URI. This method is for the case
* where the URI given to {@link PhotoViewActivity} points directly
* to a single image and does not need to be resolved via a query
* to the {@link ContentProvider}. If this value is set, it supersedes
* {@link #setPhotosUri(String)}. */
public PhotoViewIntentBuilder setResolvedPhotoUri(String resolvedPhotoUri) {
mResolvedPhotoUri = resolvedPhotoUri;
return this;
}
/**
* Sets the URI for a thumbnail preview of the photo.
*/
public PhotoViewIntentBuilder setThumbnailUri(String thumbnailUri) {
mThumbnailUri = thumbnailUri;
return this;
}
/**
* Sets the content Description for the photo
*/
public PhotoViewIntentBuilder setContentDescription(String contentDescription) {
mContentDescription = contentDescription;
return this;
}
/**
* Sets the maximum scale which an image is initially displayed at
*/
public PhotoViewIntentBuilder setMaxInitialScale(float maxScale) {
mMaxInitialScale = maxScale;
return this;
}
/**
* Enable watching the network for connectivity changes.
*
* When a change is detected, bitmap loaders will be restarted if required.
*/
public PhotoViewIntentBuilder watchNetworkConnectivityChanges() {
mWatchNetwork = true;
return this;
}
/**
* Enable a scale animation that animates the initial photo URI passed in using
* {@link #setInitialPhotoUri}.
*
* Note: To avoid janky transitions, particularly when exiting the photoviewer, ensure the
* following system UI flags are set on the root view of the relying app's activity
* (via @{link View.setSystemUiVisibility(int)}):
* {@code View.SYSTEM_UI_FLAG_VISIBLE | View.SYSTEM_UI_FLAG_LAYOUT_STABLE}
* As well, client should ensure {@code android:fitsSystemWindows} is set on the root
* content view.
*/
public PhotoViewIntentBuilder setScaleAnimation(int startX, int startY,
int startWidth, int startHeight) {
mScaleAnimation = true;
mStartX = startX;
mStartY = startY;
mStartWidth = startWidth;
mStartHeight = startHeight;
return this;
}
// If this option is turned on, then the photoViewer will be initially
// displayed with the action bar hidden. This is as opposed to the default
// behavior, where the actionBar is initially shown.
public PhotoViewIntentBuilder setActionBarHiddenInitially(
boolean actionBarHiddenInitially) {
mActionBarHiddenInitially = actionBarHiddenInitially;
return this;
}
// If this option is turned on, then the small, lo-res thumbnail will
// be scaled up to the maximum size to cover as much of the screen as
// possible while still maintaining the correct aspect ratio. This means
// that the image may appear blurry until the the full-res image is
// loaded.
// This is as opposed to the default behavior, where only part of the
// thumbnail is displayed in a small view in the center of the screen,
// and a loading spinner is displayed until the full-res image is loaded.
public PhotoViewIntentBuilder setDisplayThumbsFullScreen(
boolean displayFullScreenThumbs) {
mDisplayFullScreenThumbs = displayFullScreenThumbs;
return this;
}
/** Build the intent */
public Intent build() {
mIntent.setAction(Intent.ACTION_VIEW);
// In Lollipop, each list of photos should appear as a document in the "Recents"
// list. In earlier versions, this flag was Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET.
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT
// FLAG_ACTIVITY_CLEAR_TOP is needed for the case where the app tries to
// display a different photo while there is an existing activity instance
// for that list of photos. Since the initial photo is specified as an
// extra, without FLAG_ACTIVITY_CLEAR_TOP, the activity instance would
// just get restarted and it would display whatever photo it was last
// displaying. FLAG_ACTIVITY_CLEAR_TOP causes a new instance to be created,
// and it will display the new initial photo.
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (mPhotoIndex != null) {
mIntent.putExtra(EXTRA_PHOTO_INDEX, (int) mPhotoIndex);
}
if (mInitialPhotoUri != null) {
mIntent.putExtra(EXTRA_INITIAL_PHOTO_URI, mInitialPhotoUri);
}
if (mInitialPhotoUri != null && mPhotoIndex != null) {
throw new IllegalStateException(
"specified both photo index and photo uri");
}
if (mPhotosUri != null) {
mIntent.putExtra(EXTRA_PHOTOS_URI, mPhotosUri);
mIntent.setData(Uri.parse(mPhotosUri));
}
if (mResolvedPhotoUri != null) {
mIntent.putExtra(EXTRA_RESOLVED_PHOTO_URI, mResolvedPhotoUri);
}
if (mProjection != null) {
mIntent.putExtra(EXTRA_PROJECTION, mProjection);
}
if (mThumbnailUri != null) {
mIntent.putExtra(EXTRA_THUMBNAIL_URI, mThumbnailUri);
}
if (mContentDescription != null) {
mIntent.putExtra(EXTRA_CONTENT_DESCRIPTION, mContentDescription);
}
if (mMaxInitialScale != null) {
mIntent.putExtra(EXTRA_MAX_INITIAL_SCALE, mMaxInitialScale);
}
mIntent.putExtra(EXTRA_WATCH_NETWORK, mWatchNetwork);
mIntent.putExtra(EXTRA_SCALE_UP_ANIMATION, mScaleAnimation);
if (mScaleAnimation) {
mIntent.putExtra(EXTRA_ANIMATION_START_X, mStartX);
mIntent.putExtra(EXTRA_ANIMATION_START_Y, mStartY);
mIntent.putExtra(EXTRA_ANIMATION_START_WIDTH, mStartWidth);
mIntent.putExtra(EXTRA_ANIMATION_START_HEIGHT, mStartHeight);
}
mIntent.putExtra(EXTRA_ACTION_BAR_HIDDEN_INITIALLY, mActionBarHiddenInitially);
mIntent.putExtra(EXTRA_DISPLAY_THUMBS_FULLSCREEN, mDisplayFullScreenThumbs);
mIntent.putExtra(EXTRA_ENABLE_TIMER_LIGHTS_OUT, mEnableTimerLightsOut);
return mIntent;
}
}
}