|
Android example source code file (ViewPhotoActivity.java)
The ViewPhotoActivity.java Android example source code/* * Copyright (C) 2008 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.photostream; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.ActivityNotFoundException; import android.os.Bundle; import android.widget.TextView; import android.widget.ImageView; import android.widget.ViewAnimator; import android.widget.LinearLayout; import android.widget.Toast; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.graphics.drawable.BitmapDrawable; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.Menu; import android.view.MenuItem; import android.view.animation.AnimationUtils; import android.net.Uri; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.InputStream; import java.io.FileNotFoundException; /** * Activity that displays a photo along with its title and the date at which it was taken. * This activity also lets the user set the photo as the wallpaper. */ public class ViewPhotoActivity extends Activity implements View.OnClickListener, ViewTreeObserver.OnGlobalLayoutListener { static final String ACTION = "com.google.android.photostream.FLICKR_PHOTO"; private static final String RADAR_ACTION = "com.google.android.radar.SHOW_RADAR"; private static final String RADAR_EXTRA_LATITUDE = "latitude"; private static final String RADAR_EXTRA_LONGITUDE = "longitude"; private static final String EXTRA_PHOTO = "com.google.android.photostream.photo"; private static final String WALLPAPER_FILE_NAME = "wallpaper"; private static final int REQUEST_CROP_IMAGE = 42; private Flickr.Photo mPhoto; private ViewAnimator mSwitcher; private ImageView mPhotoView; private ViewGroup mContainer; private UserTask<?, ?, ?> mTask; private TextView mPhotoTitle; private TextView mPhotoDate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPhoto = getPhoto(); setContentView(R.layout.screen_photo); setupViews(); } /** * Starts the ViewPhotoActivity for the specified photo. * * @param context The application's environment. * @param photo The photo to display and optionally set as a wallpaper. */ static void show(Context context, Flickr.Photo photo) { final Intent intent = new Intent(ACTION); intent.putExtra(EXTRA_PHOTO, photo); context.startActivity(intent); } @Override protected void onDestroy() { super.onDestroy(); if (mTask != null && mTask.getStatus() != UserTask.Status.RUNNING) { mTask.cancel(true); } } private void setupViews() { mContainer = (ViewGroup) findViewById(R.id.container_photo); mSwitcher = (ViewAnimator) findViewById(R.id.switcher_menu); mPhotoView = (ImageView) findViewById(R.id.image_photo); mPhotoTitle = (TextView) findViewById(R.id.caption_title); mPhotoDate = (TextView) findViewById(R.id.caption_date); findViewById(R.id.menu_back).setOnClickListener(this); findViewById(R.id.menu_set).setOnClickListener(this); mPhotoTitle.setText(mPhoto.getTitle()); mPhotoDate.setText(mPhoto.getDate()); mContainer.setVisibility(View.INVISIBLE); // Sets up a view tree observer. The photo will be scaled using the size // of one of our views so we must wait for the first layout pass to be // done to make sure we have the correct size. mContainer.getViewTreeObserver().addOnGlobalLayoutListener(this); } /** * Loads the photo after the first layout. The photo is scaled using the * dimension of the ImageView that will ultimately contain the photo's * bitmap. We make sure that the ImageView is laid out at least once to * get its correct size. */ public void onGlobalLayout() { mContainer.getViewTreeObserver().removeGlobalOnLayoutListener(this); loadPhoto(mPhotoView.getMeasuredWidth(), mPhotoView.getMeasuredHeight()); } /** * Loads the photo either from the last known instance or from the network. * Loading it from the last known instance allows for fast display rotation * without having to download the photo from the network again. * * @param width The desired maximum width of the photo. * @param height The desired maximum height of the photo. */ private void loadPhoto(int width, int height) { final Object data = getLastNonConfigurationInstance(); if (data == null) { mTask = new LoadPhotoTask().execute(mPhoto, width, height); } else { mPhotoView.setImageBitmap((Bitmap) data); mSwitcher.showNext(); } } /** * Loads the {@link com.google.android.photostream.Flickr.Photo} to display * from the intent used to start the activity. * * @return The photo to display, or null if the photo cannot be found. */ public Flickr.Photo getPhoto() { final Intent intent = getIntent(); final Bundle extras = intent.getExtras(); Flickr.Photo photo = null; if (extras != null) { photo = extras.getParcelable(EXTRA_PHOTO); } return photo; } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.view_photo, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case R.id.menu_item_radar: onShowRadar(); break; } return super.onMenuItemSelected(featureId, item); } private void onShowRadar() { new ShowRadarTask().execute(mPhoto); } public void onClick(View v) { switch (v.getId()) { case R.id.menu_back: onBack(); break; case R.id.menu_set: onSet(); break; } } private void onSet() { mTask = new CropWallpaperTask().execute(mPhoto); } private void onBack() { finish(); } /** * If we successfully loaded a photo, send it to our future self to allow * for fast display rotation. By doing so, we avoid reloading the photo * from the network when the activity is taken down and recreated upon * display rotation. * * @return The Bitmap displayed in the ImageView, or null if the photo * wasn't loaded. */ @Override public Object onRetainNonConfigurationInstance() { final Drawable d = mPhotoView.getDrawable(); return d != null ? ((BitmapDrawable) d).getBitmap() : null; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // Spawns a new task to set the wallpaper in a background thread when/if // we receive a successful result from the image cropper. if (requestCode == REQUEST_CROP_IMAGE) { if (resultCode == RESULT_OK) { mTask = new SetWallpaperTask().execute(); } else { cleanupWallpaper(); showWallpaperError(); } } } private void showWallpaperError() { Toast.makeText(ViewPhotoActivity.this, R.string.error_cannot_save_file, Toast.LENGTH_SHORT).show(); } private void showWallpaperSuccess() { Toast.makeText(ViewPhotoActivity.this, R.string.success_wallpaper_set, Toast.LENGTH_SHORT).show(); } private void cleanupWallpaper() { deleteFile(WALLPAPER_FILE_NAME); mSwitcher.showNext(); } /** * Background task to load the photo from Flickr. The task loads the bitmap, * then scale it to the appropriate dimension. The task ends by readjusting * the activity's layout so that everything aligns correctly. */ private class LoadPhotoTask extends UserTask<Object, Void, Bitmap> { public Bitmap doInBackground(Object... params) { Bitmap bitmap = ((Flickr.Photo) params[0]).loadPhotoBitmap(Flickr.PhotoSize.MEDIUM); if (bitmap == null) { bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.not_found); } final int width = (Integer) params[1]; final int height = (Integer) params[2]; final Bitmap framed = ImageUtilities.scaleAndFrame(bitmap, width, height); bitmap.recycle(); return framed; } @Override public void onPostExecute(Bitmap result) { mPhotoView.setImageBitmap(result); // Find by how many pixels the title and date must be shifted on the // horizontal axis to be left aligned with the photo final int offsetX = (mPhotoView.getMeasuredWidth() - result.getWidth()) / 2; // Forces the ImageView to have the same size as its embedded bitmap // This will remove the empty space between the title/date pair and // the photo itself LinearLayout.LayoutParams params; params = (LinearLayout.LayoutParams) mPhotoView.getLayoutParams(); params.height = result.getHeight(); params.weight = 0.0f; mPhotoView.setLayoutParams(params); params = (LinearLayout.LayoutParams) mPhotoTitle.getLayoutParams(); params.leftMargin = offsetX; mPhotoTitle.setLayoutParams(params); params = (LinearLayout.LayoutParams) mPhotoDate.getLayoutParams(); params.leftMargin = offsetX; mPhotoDate.setLayoutParams(params); mSwitcher.showNext(); mContainer.startAnimation(AnimationUtils.loadAnimation(ViewPhotoActivity.this, R.anim.fade_in)); mContainer.setVisibility(View.VISIBLE); mTask = null; } } /** * Background task to crop a large version of the image. The cropped result will * be set as a wallpaper. The tasks sarts by showing the progress bar, then * downloads the large version of hthe photo into a temporary file and ends by * sending an intent to the Camera application to crop the image. */ private class CropWallpaperTask extends UserTask<Flickr.Photo, Void, Boolean> { private File mFile; @Override public void onPreExecute() { mFile = getFileStreamPath(WALLPAPER_FILE_NAME); mSwitcher.showNext(); } public Boolean doInBackground(Flickr.Photo... params) { boolean success = false; OutputStream out = null; try { out = openFileOutput(mFile.getName(), MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE); Flickr.get().downloadPhoto(params[0], Flickr.PhotoSize.LARGE, out); success = true; } catch (FileNotFoundException e) { android.util.Log.e(Flickr.LOG_TAG, "Could not download photo", e); success = false; } catch (IOException e) { android.util.Log.e(Flickr.LOG_TAG, "Could not download photo", e); success = false; } finally { if (out != null) { try { out.close(); } catch (IOException e) { success = false; } } } return success; } @Override public void onPostExecute(Boolean result) { if (!result) { cleanupWallpaper(); showWallpaperError(); } else { final int width = getWallpaperDesiredMinimumWidth(); final int height = getWallpaperDesiredMinimumHeight(); final Intent intent = new Intent("com.android.camera.action.CROP"); intent.setClassName("com.android.camera", "com.android.camera.CropImage"); intent.setData(Uri.fromFile(mFile)); intent.putExtra("outputX", width); intent.putExtra("outputY", height); intent.putExtra("aspectX", width); intent.putExtra("aspectY", height); intent.putExtra("scale", true); intent.putExtra("noFaceDetection", true); intent.putExtra("output", Uri.parse("file:/" + mFile.getAbsolutePath())); startActivityForResult(intent, REQUEST_CROP_IMAGE); } mTask = null; } } /** * Background task to set the cropped image as the wallpaper. The task simply * open the temporary file and sets it as the new wallpaper. The task ends by * deleting the temporary file and display a message to the user. */ private class SetWallpaperTask extends UserTask<Void, Void, Boolean> { public Boolean doInBackground(Void... params) { boolean success = false; InputStream in = null; try { in = openFileInput(WALLPAPER_FILE_NAME); setWallpaper(in); success = true; } catch (IOException e) { success = false; } finally { if (in != null) { try { in.close(); } catch (IOException e) { success = false; } } } return success; } @Override public void onPostExecute(Boolean result) { cleanupWallpaper(); if (!result) { showWallpaperError(); } else { showWallpaperSuccess(); } mTask = null; } } private class ShowRadarTask extends UserTask<Flickr.Photo, Void, Flickr.Location> { public Flickr.Location doInBackground(Flickr.Photo... params) { return Flickr.get().getLocation(params[0]); } @Override public void onPostExecute(Flickr.Location location) { if (location != null) { final Intent intent = new Intent(RADAR_ACTION); intent.putExtra(RADAR_EXTRA_LATITUDE, location.getLatitude()); intent.putExtra(RADAR_EXTRA_LONGITUDE, location.getLongitude()); try { startActivity(intent); } catch (ActivityNotFoundException e) { Toast.makeText(ViewPhotoActivity.this, R.string.error_cannot_find_radar, Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(ViewPhotoActivity.this, R.string.error_cannot_find_location, Toast.LENGTH_SHORT).show(); } } } } Other Android examples (source code examples)Here is a short list of links related to this Android ViewPhotoActivity.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.