1 /* 2 * Copyright (C) 2008 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.android.launcher; 18 19 import android.app.Activity; 20 import android.app.WallpaperManager; 21 import android.content.res.Resources; 22 import android.graphics.BitmapFactory; 23 import android.graphics.Bitmap; 24 import android.graphics.drawable.Drawable; 25 import android.os.Bundle; 26 import android.os.AsyncTask; 27 import android.util.Log; 28 import android.view.LayoutInflater; 29 import android.view.View; 30 import android.view.ViewGroup; 31 import android.view.Window; 32 import android.view.View.OnClickListener; 33 import android.widget.AdapterView; 34 import android.widget.BaseAdapter; 35 import android.widget.Gallery; 36 import android.widget.ImageView; 37 38 import java.io.IOException; 39 import java.util.ArrayList; 40 41 public class WallpaperChooser extends Activity implements AdapterView.OnItemSelectedListener, 42 OnClickListener { 43 44 private Gallery mGallery; 45 private ImageView mImageView; 46 private boolean mIsWallpaperSet; 47 48 private Bitmap mBitmap; 49 50 private ArrayList<Integer> mThumbs; 51 private ArrayList<Integer> mImages; 52 private WallpaperLoader mLoader; 53 54 @Override onCreate(Bundle icicle)55 public void onCreate(Bundle icicle) { 56 super.onCreate(icicle); 57 requestWindowFeature(Window.FEATURE_NO_TITLE); 58 59 findWallpapers(); 60 61 setContentView(R.layout.wallpaper_chooser); 62 63 mGallery = (Gallery) findViewById(R.id.gallery); 64 mGallery.setAdapter(new ImageAdapter(this)); 65 mGallery.setOnItemSelectedListener(this); 66 mGallery.setCallbackDuringFling(false); 67 68 findViewById(R.id.set).setOnClickListener(this); 69 70 mImageView = (ImageView) findViewById(R.id.wallpaper); 71 } 72 findWallpapers()73 private void findWallpapers() { 74 mThumbs = new ArrayList<Integer>(24); 75 mImages = new ArrayList<Integer>(24); 76 77 final Resources resources = getResources(); 78 final String packageName = getApplication().getPackageName(); 79 80 addWallpapers(resources, packageName, R.array.wallpapers); 81 addWallpapers(resources, packageName, R.array.extra_wallpapers); 82 } 83 addWallpapers(Resources resources, String packageName, int list)84 private void addWallpapers(Resources resources, String packageName, int list) { 85 final String[] extras = resources.getStringArray(list); 86 for (String extra : extras) { 87 int res = resources.getIdentifier(extra, "drawable", packageName); 88 if (res != 0) { 89 final int thumbRes = resources.getIdentifier(extra + "_small", 90 "drawable", packageName); 91 92 if (thumbRes != 0) { 93 mThumbs.add(thumbRes); 94 mImages.add(res); 95 } 96 } 97 } 98 } 99 100 @Override onResume()101 protected void onResume() { 102 super.onResume(); 103 mIsWallpaperSet = false; 104 } 105 106 @Override onDestroy()107 protected void onDestroy() { 108 super.onDestroy(); 109 110 if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) { 111 mLoader.cancel(true); 112 mLoader = null; 113 } 114 } 115 onItemSelected(AdapterView parent, View v, int position, long id)116 public void onItemSelected(AdapterView parent, View v, int position, long id) { 117 if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) { 118 mLoader.cancel(); 119 } 120 mLoader = (WallpaperLoader) new WallpaperLoader().execute(position); 121 } 122 123 /* 124 * When using touch if you tap an image it triggers both the onItemClick and 125 * the onTouchEvent causing the wallpaper to be set twice. Ensure we only 126 * set the wallpaper once. 127 */ selectWallpaper(int position)128 private void selectWallpaper(int position) { 129 if (mIsWallpaperSet) { 130 return; 131 } 132 133 mIsWallpaperSet = true; 134 try { 135 WallpaperManager wpm = (WallpaperManager)getSystemService(WALLPAPER_SERVICE); 136 wpm.setResource(mImages.get(position)); 137 setResult(RESULT_OK); 138 finish(); 139 } catch (IOException e) { 140 Log.e(Launcher.LOG_TAG, "Failed to set wallpaper: " + e); 141 } 142 } 143 onNothingSelected(AdapterView parent)144 public void onNothingSelected(AdapterView parent) { 145 } 146 147 private class ImageAdapter extends BaseAdapter { 148 private LayoutInflater mLayoutInflater; 149 ImageAdapter(WallpaperChooser context)150 ImageAdapter(WallpaperChooser context) { 151 mLayoutInflater = context.getLayoutInflater(); 152 } 153 getCount()154 public int getCount() { 155 return mThumbs.size(); 156 } 157 getItem(int position)158 public Object getItem(int position) { 159 return position; 160 } 161 getItemId(int position)162 public long getItemId(int position) { 163 return position; 164 } 165 getView(int position, View convertView, ViewGroup parent)166 public View getView(int position, View convertView, ViewGroup parent) { 167 ImageView image; 168 169 if (convertView == null) { 170 image = (ImageView) mLayoutInflater.inflate(R.layout.wallpaper_item, parent, false); 171 } else { 172 image = (ImageView) convertView; 173 } 174 175 int thumbRes = mThumbs.get(position); 176 image.setImageResource(thumbRes); 177 Drawable thumbDrawable = image.getDrawable(); 178 if (thumbDrawable != null) { 179 thumbDrawable.setDither(true); 180 } else { 181 Log.e(Launcher.LOG_TAG, String.format( 182 "Error decoding thumbnail resId=%d for wallpaper #%d", 183 thumbRes, position)); 184 } 185 return image; 186 } 187 } 188 onClick(View v)189 public void onClick(View v) { 190 selectWallpaper(mGallery.getSelectedItemPosition()); 191 } 192 193 class WallpaperLoader extends AsyncTask<Integer, Void, Bitmap> { 194 BitmapFactory.Options mOptions; 195 WallpaperLoader()196 WallpaperLoader() { 197 mOptions = new BitmapFactory.Options(); 198 mOptions.inDither = false; 199 mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888; 200 } 201 doInBackground(Integer... params)202 protected Bitmap doInBackground(Integer... params) { 203 if (isCancelled()) return null; 204 try { 205 return BitmapFactory.decodeResource(getResources(), 206 mImages.get(params[0]), mOptions); 207 } catch (OutOfMemoryError e) { 208 return null; 209 } 210 } 211 212 @Override onPostExecute(Bitmap b)213 protected void onPostExecute(Bitmap b) { 214 if (b == null) return; 215 216 if (!isCancelled() && !mOptions.mCancel) { 217 // Help the GC 218 if (mBitmap != null) { 219 mBitmap.recycle(); 220 } 221 222 final ImageView view = mImageView; 223 view.setImageBitmap(b); 224 225 mBitmap = b; 226 227 final Drawable drawable = view.getDrawable(); 228 drawable.setFilterBitmap(true); 229 drawable.setDither(true); 230 231 view.postInvalidate(); 232 233 mLoader = null; 234 } else { 235 b.recycle(); 236 } 237 } 238 cancel()239 void cancel() { 240 mOptions.requestCancelDecode(); 241 super.cancel(true); 242 } 243 } 244 } 245