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.Res; 40 41 /** 42 * Wallpaper picker for the camera application. This just redirects to the 43 * standard pick action. 44 */ 45 public class Wallpaper extends Activity { 46 private static final String LOG_TAG = "Wallpaper"; 47 static final int PHOTO_PICKED = 1; 48 static final int CROP_DONE = 2; 49 50 static final int SHOW_PROGRESS = 0; 51 static final int FINISH = 1; 52 53 static final String DO_LAUNCH_ICICLE = "do_launch"; 54 static final String TEMP_FILE_PATH_ICICLE = "temp_file_path"; 55 56 private ProgressDialog mProgressDialog = null; 57 private boolean mDoLaunch = true; 58 private File mTempFile; 59 60 private final Handler mHandler = new Handler() { 61 @Override 62 public void handleMessage(Message msg) { 63 switch (msg.what) { 64 case SHOW_PROGRESS: { 65 CharSequence c = getText(Res.string.wallpaper); 66 mProgressDialog = ProgressDialog.show(Wallpaper.this, "", c, true, false); 67 break; 68 } 69 case FINISH: { 70 closeProgressDialog(); 71 setResult(RESULT_OK); 72 finish(); 73 break; 74 } 75 } 76 } 77 }; 78 79 static class SetWallpaperThread extends Thread { 80 private final Bitmap mBitmap; 81 private final Handler mHandler; 82 private final Context mContext; 83 private final File mFile; 84 85 public SetWallpaperThread(Bitmap bitmap, Handler handler, Context context, File file) { 86 mBitmap = bitmap; 87 mHandler = handler; 88 mContext = context; 89 mFile = file; 90 } 91 92 @Override 93 public void run() { 94 try { 95 WallpaperManager.getInstance(mContext).setBitmap(mBitmap); 96 } catch (IOException e) { 97 Log.e(LOG_TAG, "Failed to set wallpaper.", e); 98 } finally { 99 mHandler.sendEmptyMessage(FINISH); 100 mFile.delete(); 101 } 102 } 103 } 104 105 private synchronized void closeProgressDialog() { 106 if (mProgressDialog != null) { 107 mProgressDialog.dismiss(); 108 mProgressDialog = null; 109 } 110 } 111 112 @Override 113 protected void onCreate(Bundle icicle) { 114 super.onCreate(icicle); 115 if (icicle != null) { 116 mDoLaunch = icicle.getBoolean(DO_LAUNCH_ICICLE); 117 mTempFile = new File(icicle.getString(TEMP_FILE_PATH_ICICLE)); 118 } 119 } 120 121 @Override 122 protected void onSaveInstanceState(Bundle icicle) { 123 icicle.putBoolean(DO_LAUNCH_ICICLE, mDoLaunch); 124 icicle.putString(TEMP_FILE_PATH_ICICLE, mTempFile.getAbsolutePath()); 125 } 126 127 @Override 128 protected void onPause() { 129 closeProgressDialog(); 130 super.onPause(); 131 } 132 133 @Override 134 protected void onResume() { 135 super.onResume(); 136 if (!mDoLaunch) { 137 return; 138 } 139 Uri imageToUse = getIntent().getData(); 140 if (imageToUse != null) { 141 Intent intent = new Intent(); 142 intent.setClass(this, CropImage.class); 143 intent.setData(imageToUse); 144 formatIntent(intent); 145 startActivityForResult(intent, CROP_DONE); 146 } else { 147 Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); 148 intent.setType("image/*"); 149 intent.putExtra("crop", "true"); 150 formatIntent(intent); 151 startActivityForResult(intent, PHOTO_PICKED); 152 } 153 } 154 155 protected void formatIntent(Intent intent) { 156 // TODO: A temporary file is NOT necessary 157 // The CropImage intent should be able to set the wallpaper directly 158 // without writing to a file, which we then need to read here to write 159 // it again as the final wallpaper, this is silly 160 mTempFile = getFileStreamPath("temp-wallpaper"); 161 mTempFile.getParentFile().mkdirs(); 162 163 int width = getWallpaperDesiredMinimumWidth(); 164 int height = getWallpaperDesiredMinimumHeight(); 165 intent.putExtra("outputX", width); 166 intent.putExtra("outputY", height); 167 intent.putExtra("aspectX", width); 168 intent.putExtra("aspectY", height); 169 intent.putExtra("scale", true); 170 intent.putExtra("noFaceDetection", true); 171 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile)); 172 intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.name()); 173 // TODO: we should have an extra called "setWallpaper" to ask CropImage 174 // to set the cropped image as a wallpaper directly. This means the 175 // SetWallpaperThread should be moved out of this class to CropImage 176 } 177 178 @Override 179 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 180 if ((requestCode == PHOTO_PICKED || requestCode == CROP_DONE) && (resultCode == RESULT_OK) && (data != null)) { 181 try { 182 InputStream s = new FileInputStream(mTempFile); 183 try { 184 Bitmap bitmap = BitmapFactory.decodeStream(s); 185 if (bitmap == null) { 186 Log.e(LOG_TAG, "Failed to set wallpaper. " + "Couldn't get bitmap for path " + mTempFile); 187 } else { 188 mHandler.sendEmptyMessage(SHOW_PROGRESS); 189 new SetWallpaperThread(bitmap, mHandler, this, mTempFile).start(); 190 } 191 mDoLaunch = false; 192 } finally { 193 Util.closeSilently(s); 194 } 195 } catch (FileNotFoundException ex) { 196 Log.e(LOG_TAG, "file not found: " + mTempFile, ex); 197 } 198 } else { 199 setResult(RESULT_CANCELED); 200 finish(); 201 } 202 } 203 } 204