1f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks/* 2f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * Copyright (C) 2007 The Android Open Source Project 3f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * 4f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * Licensed under the Apache License, Version 2.0 (the "License"); 5f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * you may not use this file except in compliance with the License. 6f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * You may obtain a copy of the License at 7f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * 8f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * http://www.apache.org/licenses/LICENSE-2.0 9f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * 10f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * Unless required by applicable law or agreed to in writing, software 11f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * distributed under the License is distributed on an "AS IS" BASIS, 12f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * See the License for the specific language governing permissions and 14f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * limitations under the License. 15f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks */ 16f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 173c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chenpackage com.cooliris.media; 183c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen 19f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.app.Activity; 20f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.app.ProgressDialog; 21f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Context; 22f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Intent; 23f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.graphics.Bitmap; 24f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.graphics.BitmapFactory; 25f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.net.Uri; 26f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Bundle; 27f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Handler; 28f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Message; 29f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.provider.MediaStore; 30f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.util.Log; 31f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 32f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.io.File; 33f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.io.FileInputStream; 34f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.io.FileNotFoundException; 35f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.io.IOException; 36f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.io.InputStream; 37f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 3829dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Changimport com.cooliris.app.Res; 3929dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang 40f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks/** 41f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * Wallpaper picker for the camera application. This just redirects to the 42f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * standard pick action. 43f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks */ 44f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspublic class Wallpaper extends Activity { 45f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private static final String LOG_TAG = "Wallpaper"; 46f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks static final int PHOTO_PICKED = 1; 47f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks static final int CROP_DONE = 2; 48f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 49f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks static final int SHOW_PROGRESS = 0; 50f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks static final int FINISH = 1; 51f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 52f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks static final String DO_LAUNCH_ICICLE = "do_launch"; 53f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks static final String TEMP_FILE_PATH_ICICLE = "temp_file_path"; 54f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 55f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private ProgressDialog mProgressDialog = null; 56f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mDoLaunch = true; 57f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private File mTempFile; 58f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 59f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private final Handler mHandler = new Handler() { 60f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks @Override 61f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void handleMessage(Message msg) { 62f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks switch (msg.what) { 631bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks case SHOW_PROGRESS: { 6429dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang CharSequence c = getText(Res.string.wallpaper); 651bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks mProgressDialog = ProgressDialog.show(Wallpaper.this, "", c, true, false); 661bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks break; 671bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks } 681bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks case FINISH: { 691bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks closeProgressDialog(); 701bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks setResult(RESULT_OK); 711bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks finish(); 721bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks break; 731bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks } 74f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 75f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 76f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }; 77f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 78f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks static class SetWallpaperThread extends Thread { 79f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private final Bitmap mBitmap; 80f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private final Handler mHandler; 81f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private final Context mContext; 82f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private final File mFile; 83f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 841bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks public SetWallpaperThread(Bitmap bitmap, Handler handler, Context context, File file) { 85f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mBitmap = bitmap; 86f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mHandler = handler; 87f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mContext = context; 88f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mFile = file; 89f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 90f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 91f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks @Override 92f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 93f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 94f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mContext.setWallpaper(mBitmap); 95f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (IOException e) { 96f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Log.e(LOG_TAG, "Failed to set wallpaper.", e); 97f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } finally { 98f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mHandler.sendEmptyMessage(FINISH); 99f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mFile.delete(); 100f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 101f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 102f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 103f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 104f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private synchronized void closeProgressDialog() { 105f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mProgressDialog != null) { 106f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mProgressDialog.dismiss(); 107f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mProgressDialog = null; 108f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 109f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 110f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 111f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks @Override 112f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks protected void onCreate(Bundle icicle) { 113f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks super.onCreate(icicle); 114f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (icicle != null) { 115f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDoLaunch = icicle.getBoolean(DO_LAUNCH_ICICLE); 116f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mTempFile = new File(icicle.getString(TEMP_FILE_PATH_ICICLE)); 117f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 118f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 119f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 120f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks @Override 121f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks protected void onSaveInstanceState(Bundle icicle) { 122f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks icicle.putBoolean(DO_LAUNCH_ICICLE, mDoLaunch); 123f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks icicle.putString(TEMP_FILE_PATH_ICICLE, mTempFile.getAbsolutePath()); 124f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 125f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 126f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks @Override 127f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks protected void onPause() { 128f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks closeProgressDialog(); 129f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks super.onPause(); 130f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 131f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 132f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks @Override 133f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks protected void onResume() { 134f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks super.onResume(); 135f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (!mDoLaunch) { 136f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 137f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 138f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Uri imageToUse = getIntent().getData(); 139f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (imageToUse != null) { 140f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Intent intent = new Intent(); 14111f319e713e9f2cd2d1b4293ad028050f8667453Venkat Krishnaraj intent.setClass(this, CropImage.class); 142f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks intent.setData(imageToUse); 143f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks formatIntent(intent); 144f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks startActivityForResult(intent, CROP_DONE); 145f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 146f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); 147f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks intent.setType("image/*"); 148f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks intent.putExtra("crop", "true"); 149f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks formatIntent(intent); 150f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks startActivityForResult(intent, PHOTO_PICKED); 151f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 152f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 153f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 154f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks protected void formatIntent(Intent intent) { 155f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // TODO: A temporary file is NOT necessary 156f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // The CropImage intent should be able to set the wallpaper directly 157f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // without writing to a file, which we then need to read here to write 158f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // it again as the final wallpaper, this is silly 159f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mTempFile = getFileStreamPath("temp-wallpaper"); 160f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mTempFile.getParentFile().mkdirs(); 161f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 162f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int width = getWallpaperDesiredMinimumWidth(); 163f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int height = getWallpaperDesiredMinimumHeight(); 1641bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks intent.putExtra("outputX", width); 1651bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks intent.putExtra("outputY", height); 1661bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks intent.putExtra("aspectX", width); 1671bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks intent.putExtra("aspectY", height); 1681bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks intent.putExtra("scale", true); 169f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks intent.putExtra("noFaceDetection", true); 170f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile)); 171f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.name()); 172f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // TODO: we should have an extra called "setWallpaper" to ask CropImage 173f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // to set the cropped image as a wallpaper directly. This means the 174f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // SetWallpaperThread should be moved out of this class to CropImage 175f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 176f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 177f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks @Override 1781bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks protected void onActivityResult(int requestCode, int resultCode, Intent data) { 1791bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks if ((requestCode == PHOTO_PICKED || requestCode == CROP_DONE) && (resultCode == RESULT_OK) && (data != null)) { 180f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 181f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks InputStream s = new FileInputStream(mTempFile); 182f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 183f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Bitmap bitmap = BitmapFactory.decodeStream(s); 184f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (bitmap == null) { 1851bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks Log.e(LOG_TAG, "Failed to set wallpaper. " + "Couldn't get bitmap for path " + mTempFile); 186f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 187f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mHandler.sendEmptyMessage(SHOW_PROGRESS); 1881bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks new SetWallpaperThread(bitmap, mHandler, this, mTempFile).start(); 189f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 190f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDoLaunch = false; 191f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } finally { 192f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Util.closeSilently(s); 193f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 194f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (FileNotFoundException ex) { 195f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Log.e(LOG_TAG, "file not found: " + mTempFile, ex); 196f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 197f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 198f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks setResult(RESULT_CANCELED); 199f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks finish(); 200f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 201f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 202f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks} 203