/* * 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_MAX_INITIAL_SCALE = "max_scale"; public static final String EXTRA_WATCH_NETWORK = "watch_network"; // 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 clazz) { return new PhotoViewIntentBuilder(context, clazz); } /** Gets a new photo view intent builder */ public static PhotoViewIntentBuilder newPhotoViewIntentBuilder( Context context, Class 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 maximum scale to display images at before */ private Float mMaxInitialScale; /** * 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; } /** 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 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 (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); return mIntent; } } }