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