1 /* 2 * Copyright (C) 2009 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.camera; 18 19 import com.android.gallery.R; 20 21 import android.appwidget.AppWidgetManager; 22 import android.appwidget.AppWidgetProvider; 23 import android.content.ContentValues; 24 import android.content.Context; 25 import android.database.Cursor; 26 import android.database.sqlite.SQLiteDatabase; 27 import android.database.sqlite.SQLiteException; 28 import android.database.sqlite.SQLiteOpenHelper; 29 import android.graphics.Bitmap; 30 import android.graphics.BitmapFactory; 31 import android.util.Log; 32 import android.widget.RemoteViews; 33 34 import java.io.ByteArrayOutputStream; 35 import java.io.IOException; 36 37 /** 38 * Simple widget to show a user-selected picture. 39 */ 40 public class PhotoAppWidgetProvider extends AppWidgetProvider { 41 private static final String TAG = "PhotoAppWidgetProvider"; 42 private static final boolean LOGD = true; 43 44 @Override 45 public void onUpdate(Context context, AppWidgetManager appWidgetManager, 46 int[] appWidgetIds) { 47 // Update each requested appWidgetId with its unique photo 48 PhotoDatabaseHelper helper = new PhotoDatabaseHelper(context); 49 for (int appWidgetId : appWidgetIds) { 50 int[] specificAppWidget = new int[] { appWidgetId }; 51 RemoteViews views = buildUpdate(context, appWidgetId, helper); 52 if (LOGD) { 53 Log.d(TAG, "sending out views=" + views 54 + " for id=" + appWidgetId); 55 } 56 appWidgetManager.updateAppWidget(specificAppWidget, views); 57 } 58 helper.close(); 59 } 60 61 @Override 62 public void onDeleted(Context context, int[] appWidgetIds) { 63 // Clean deleted photos out of our database 64 PhotoDatabaseHelper helper = new PhotoDatabaseHelper(context); 65 for (int appWidgetId : appWidgetIds) { 66 helper.deletePhoto(appWidgetId); 67 } 68 helper.close(); 69 } 70 71 /** 72 * Load photo for given widget and build {@link RemoteViews} for it. 73 */ 74 static RemoteViews buildUpdate(Context context, int appWidgetId, 75 PhotoDatabaseHelper helper) { 76 RemoteViews views = null; 77 Bitmap bitmap = helper.getPhoto(appWidgetId); 78 if (bitmap != null) { 79 views = new RemoteViews(context.getPackageName(), 80 R.layout.photo_frame); 81 views.setImageViewBitmap(R.id.photo, bitmap); 82 } 83 return views; 84 } 85 86 static class PhotoDatabaseHelper extends SQLiteOpenHelper { 87 private static final String DATABASE_NAME = "launcher.db"; 88 89 private static final int DATABASE_VERSION = 2; 90 91 static final String TABLE_PHOTOS = "photos"; 92 static final String FIELD_APPWIDGET_ID = "appWidgetId"; 93 static final String FIELD_PHOTO_BLOB = "photoBlob"; 94 95 PhotoDatabaseHelper(Context context) { 96 super(context, DATABASE_NAME, null, DATABASE_VERSION); 97 } 98 99 @Override 100 public void onCreate(SQLiteDatabase db) { 101 db.execSQL("CREATE TABLE " + TABLE_PHOTOS + " (" + 102 FIELD_APPWIDGET_ID + " INTEGER PRIMARY KEY," + 103 FIELD_PHOTO_BLOB + " BLOB" + 104 ");"); 105 } 106 107 @Override 108 public void onUpgrade(SQLiteDatabase db, int oldVersion, 109 int newVersion) { 110 int version = oldVersion; 111 112 if (version != DATABASE_VERSION) { 113 Log.w(TAG, "Destroying all old data."); 114 db.execSQL("DROP TABLE IF EXISTS " + TABLE_PHOTOS); 115 onCreate(db); 116 } 117 } 118 119 /** 120 * Store the given bitmap in this database for the given appWidgetId. 121 */ 122 public boolean setPhoto(int appWidgetId, Bitmap bitmap) { 123 boolean success = false; 124 try { 125 // Try go guesstimate how much space the icon will take when 126 // serialized to avoid unnecessary allocations/copies during 127 // the write. 128 int size = bitmap.getWidth() * bitmap.getHeight() * 4; 129 ByteArrayOutputStream out = new ByteArrayOutputStream(size); 130 bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); 131 out.flush(); 132 out.close(); 133 134 ContentValues values = new ContentValues(); 135 values.put(PhotoDatabaseHelper.FIELD_APPWIDGET_ID, appWidgetId); 136 values.put(PhotoDatabaseHelper.FIELD_PHOTO_BLOB, 137 out.toByteArray()); 138 139 SQLiteDatabase db = getWritableDatabase(); 140 db.insertOrThrow(PhotoDatabaseHelper.TABLE_PHOTOS, null, 141 values); 142 143 success = true; 144 } catch (SQLiteException e) { 145 Log.e(TAG, "Could not open database", e); 146 } catch (IOException e) { 147 Log.e(TAG, "Could not serialize photo", e); 148 } 149 if (LOGD) { 150 Log.d(TAG, "setPhoto success=" + success); 151 } 152 return success; 153 } 154 155 static final String[] PHOTOS_PROJECTION = { 156 FIELD_PHOTO_BLOB, 157 }; 158 159 static final int INDEX_PHOTO_BLOB = 0; 160 161 /** 162 * Inflate and return a bitmap for the given appWidgetId. 163 */ 164 public Bitmap getPhoto(int appWidgetId) { 165 Cursor c = null; 166 Bitmap bitmap = null; 167 try { 168 SQLiteDatabase db = getReadableDatabase(); 169 String selection = String.format("%s=%d", FIELD_APPWIDGET_ID, 170 appWidgetId); 171 c = db.query(TABLE_PHOTOS, PHOTOS_PROJECTION, selection, null, 172 null, null, null, null); 173 174 if (c != null && LOGD) { 175 Log.d(TAG, "getPhoto query count=" + c.getCount()); 176 } 177 178 if (c != null && c.moveToFirst()) { 179 byte[] data = c.getBlob(INDEX_PHOTO_BLOB); 180 if (data != null) { 181 bitmap = BitmapFactory.decodeByteArray(data, 0, 182 data.length); 183 } 184 } 185 } catch (SQLiteException e) { 186 Log.e(TAG, "Could not load photo from database", e); 187 } finally { 188 if (c != null) { 189 c.close(); 190 } 191 } 192 return bitmap; 193 } 194 195 /** 196 * Remove any bitmap associated with the given appWidgetId. 197 */ 198 public void deletePhoto(int appWidgetId) { 199 try { 200 SQLiteDatabase db = getWritableDatabase(); 201 String whereClause = String.format("%s=%d", FIELD_APPWIDGET_ID, 202 appWidgetId); 203 db.delete(TABLE_PHOTOS, whereClause, null); 204 } catch (SQLiteException e) { 205 Log.e(TAG, "Could not delete photo from database", e); 206 } 207 } 208 } 209 210 } 211 212