Util.java revision 026dff889c80763fc322ed03e2d3a76750320138
1101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin/* 2101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Copyright (C) 2009 The Android Open Source Project 3101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * 4101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * you may not use this file except in compliance with the License. 6101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * You may obtain a copy of the License at 7101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * 8101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * http://www.apache.org/licenses/LICENSE-2.0 9101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * 10101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Unless required by applicable law or agreed to in writing, software 11101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * See the License for the specific language governing permissions and 14101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * limitations under the License. 15101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin */ 16101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 17937fc48b37fafe3ffc8f4b52bd9a171bbb4d3a37Owen Linpackage com.android.camera; 18101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 190a475e11e2ceadbaa70308b52e06f4e6d9e56f12Chih-Chung Changimport com.android.camera.gallery.IImage; 200a475e11e2ceadbaa70308b52e06f4e6d9e56f12Chih-Chung Chang 21601ce56b034f111b2875e7636776f2f359f6a156Owen Linimport android.app.ProgressDialog; 22c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Changimport android.content.ContentResolver; 23601ce56b034f111b2875e7636776f2f359f6a156Owen Linimport android.content.Context; 24bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Changimport android.content.Intent; 25101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport android.graphics.Bitmap; 26101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport android.graphics.BitmapFactory; 2796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Changimport android.graphics.Canvas; 28101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport android.graphics.Matrix; 2996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Changimport android.graphics.Rect; 30101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport android.media.MediaMetadataRetriever; 31c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Changimport android.net.Uri; 32482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Linimport android.os.Handler; 33101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport android.os.ParcelFileDescriptor; 34101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport android.util.Log; 35601ce56b034f111b2875e7636776f2f359f6a156Owen Linimport android.view.View; 36601ce56b034f111b2875e7636776f2f359f6a156Owen Linimport android.view.View.OnClickListener; 37101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 38101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport java.io.ByteArrayOutputStream; 39101d528d59f447847d5c6b7578642132c2b76f4fOwen Linimport java.io.Closeable; 40c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Changimport java.io.FileDescriptor; 41d30b5877fbdedcebc0af5cccffddccfe9b11cb0bOwen Linimport java.io.IOException; 42101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 43101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin/** 44101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Collection of utility functions used in this package. 45101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin */ 46101d528d59f447847d5c6b7578642132c2b76f4fOwen Linpublic class Util { 47101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin private static final String TAG = "db.Util"; 48101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 49601ce56b034f111b2875e7636776f2f359f6a156Owen Lin private static OnClickListener sNullOnClickListener; 50601ce56b034f111b2875e7636776f2f359f6a156Owen Lin 51101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin private Util() { 52101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 53101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 54101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // Rotates the bitmap by the specified degree. 55101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // If a new bitmap is created, the original bitmap is recycled. 56101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin public static Bitmap rotate(Bitmap b, int degrees) { 57101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (degrees != 0 && b != null) { 58101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Matrix m = new Matrix(); 59101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin m.setRotate(degrees, 60101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin (float) b.getWidth() / 2, (float) b.getHeight() / 2); 61101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin try { 62101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap b2 = Bitmap.createBitmap( 63101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin b, 0, 0, b.getWidth(), b.getHeight(), m, true); 64101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (b != b2) { 65101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin b.recycle(); 66101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin b = b2; 67101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 68101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } catch (OutOfMemoryError ex) { 69101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // We have no memory to rotate. Return the original bitmap. 70101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 71101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 72101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return b; 73101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 74101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 75101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin /* 76101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Compute the sample size as a function of the image size and the target. 77101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Scale the image down so that both the width and height are just above the 78101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * target. If this means that one of the dimension goes from above the 79101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * target to below the target (e.g. given a width of 480 and an image width 80101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * of 600 but sample size of 2 -- i.e. new width 300 -- bump the sample size 81101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * down by 1. 82101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin */ 83101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin public static int computeSampleSize( 84101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin BitmapFactory.Options options, int target) { 85101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin int w = options.outWidth; 86101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin int h = options.outHeight; 87101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 88101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin int candidateW = w / target; 89101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin int candidateH = h / target; 90101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin int candidate = Math.max(candidateW, candidateH); 91101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 92101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (candidate == 0) return 1; 93101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 94101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (candidate > 1) { 95101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if ((w > target) && (w / candidate) < target) candidate -= 1; 96101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 97101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 98101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (candidate > 1) { 99101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if ((h > target) && (h / candidate) < target) candidate -= 1; 100101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 101101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 102101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return candidate; 103101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 104101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 10596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang public static Bitmap transform(Matrix scaler, 10696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Bitmap source, 10796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int targetWidth, 10896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int targetHeight, 10996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang boolean scaleUp) { 11096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int deltaX = source.getWidth() - targetWidth; 11196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int deltaY = source.getHeight() - targetHeight; 11296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang if (!scaleUp && (deltaX < 0 || deltaY < 0)) { 11396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang /* 11496b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang * In this case the bitmap is smaller, at least in one dimension, 11596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang * than the target. Transform it by placing as much of the image 11696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang * as possible into the target and leaving the top/bottom or 11796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang * left/right (or both) black. 11896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang */ 11996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight, 12096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Bitmap.Config.ARGB_8888); 12196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Canvas c = new Canvas(b2); 12296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 12396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int deltaXHalf = Math.max(0, deltaX / 2); 12496b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int deltaYHalf = Math.max(0, deltaY / 2); 12596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Rect src = new Rect( 12696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang deltaXHalf, 12796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang deltaYHalf, 12896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang deltaXHalf + Math.min(targetWidth, source.getWidth()), 12996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang deltaYHalf + Math.min(targetHeight, source.getHeight())); 13096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int dstX = (targetWidth - src.width()) / 2; 13196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int dstY = (targetHeight - src.height()) / 2; 13296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Rect dst = new Rect( 13396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang dstX, 13496b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang dstY, 13596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang targetWidth - dstX, 13696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang targetHeight - dstY); 13796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang c.drawBitmap(source, src, dst, null); 13896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang return b2; 13996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } 14096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang float bitmapWidthF = source.getWidth(); 14196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang float bitmapHeightF = source.getHeight(); 14296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 14396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang float bitmapAspect = bitmapWidthF / bitmapHeightF; 14458e94eddd371a9bb7c04936dbeb99615fd1a0c2cChih-Chung Chang float viewAspect = (float) targetWidth / targetHeight; 14596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 14696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang if (bitmapAspect > viewAspect) { 14796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang float scale = targetHeight / bitmapHeightF; 14896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang if (scale < .9F || scale > 1F) { 14996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang scaler.setScale(scale, scale); 15096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } else { 15196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang scaler = null; 15296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } 15396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } else { 15496b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang float scale = targetWidth / bitmapWidthF; 15596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang if (scale < .9F || scale > 1F) { 15696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang scaler.setScale(scale, scale); 15796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } else { 15896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang scaler = null; 15996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } 16096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } 16196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 16296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Bitmap b1; 16396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang if (scaler != null) { 16496b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang // this is used for minithumb and crop, so we want to filter here. 16596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang b1 = Bitmap.createBitmap(source, 0, 0, 16696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang source.getWidth(), source.getHeight(), scaler, true); 16796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } else { 16896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang b1 = source; 16996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } 17096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 17196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int dx1 = Math.max(0, b1.getWidth() - targetWidth); 17296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang int dy1 = Math.max(0, b1.getHeight() - targetHeight); 17396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 17496b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Bitmap b2 = Bitmap.createBitmap( 17596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang b1, 17696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang dx1 / 2, 17796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang dy1 / 2, 17896b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang targetWidth, 17996b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang targetHeight); 18096b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 18196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang if (b1 != source) { 18296b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang b1.recycle(); 18396b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } 18496b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 18596b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang return b2; 18696b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang } 18796b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang 188101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin /** 189101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Creates a centered bitmap of the desired size. Recycles the input. 190101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * @param source 191101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin */ 192101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin public static Bitmap extractMiniThumb( 193101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap source, int width, int height) { 194101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return Util.extractMiniThumb(source, width, height, true); 195101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 196101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 197101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin public static Bitmap extractMiniThumb( 198101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap source, int width, int height, boolean recycle) { 199101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (source == null) { 200101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return null; 201101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 202101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 203101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin float scale; 204101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (source.getWidth() < source.getHeight()) { 205101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin scale = width / (float) source.getWidth(); 206101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } else { 207101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin scale = height / (float) source.getHeight(); 208101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 209101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Matrix matrix = new Matrix(); 210101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin matrix.setScale(scale, scale); 21196b3c6ee6d93c136bb8270521158a989584966b1Chih-Chung Chang Bitmap miniThumbnail = transform(matrix, source, width, height, false); 212101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 213101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (recycle && miniThumbnail != source) { 214101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin source.recycle(); 215101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 216101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return miniThumbnail; 217101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 218101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 219101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin /** 220101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Creates a byte[] for a given bitmap of the desired size. Recycles the 221101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * input bitmap. 222101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin */ 223101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin public static byte[] miniThumbData(Bitmap source) { 224101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (source == null) return null; 225101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 226101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap miniThumbnail = extractMiniThumb( 2270a475e11e2ceadbaa70308b52e06f4e6d9e56f12Chih-Chung Chang source, IImage.MINI_THUMB_TARGET_SIZE, 2280a475e11e2ceadbaa70308b52e06f4e6d9e56f12Chih-Chung Chang IImage.MINI_THUMB_TARGET_SIZE); 229101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 230101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin ByteArrayOutputStream miniOutStream = new ByteArrayOutputStream(); 231101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin miniThumbnail.compress(Bitmap.CompressFormat.JPEG, 75, miniOutStream); 232101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin miniThumbnail.recycle(); 233101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 234101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin try { 235101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin miniOutStream.close(); 236101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin byte [] data = miniOutStream.toByteArray(); 237101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return data; 238101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } catch (java.io.IOException ex) { 239101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Log.e(TAG, "got exception ex " + ex); 240101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 241101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return null; 242101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 243101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 244101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin /** 245101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * Create a video thumbnail for a video. May return null if the video is 246101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * corrupt. 247101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * 248101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin * @param filePath 249101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin */ 250101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin public static Bitmap createVideoThumbnail(String filePath) { 251101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin Bitmap bitmap = null; 252101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 253101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin try { 254101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY); 255101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin retriever.setDataSource(filePath); 256101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin bitmap = retriever.captureFrame(); 257101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } catch (IllegalArgumentException ex) { 258101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // Assume this is a corrupt video file 259101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } catch (RuntimeException ex) { 260101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // Assume this is a corrupt video file. 261101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } finally { 262101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin try { 263101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin retriever.release(); 264101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } catch (RuntimeException ex) { 265101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // Ignore failures while cleaning up. 266101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 267101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 268101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return bitmap; 269101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 270101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 271bbc2f2f15a865cf0330cd78a6ea67177c5863b3bOwen Lin public static <T> int indexOf(T [] array, T s) { 272101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin for (int i = 0; i < array.length; i++) { 273101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (array[i].equals(s)) { 274101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return i; 275101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 276101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 277101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin return -1; 278101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 279101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 280724e9b3db93677b753c1267a716e30e6cf5ff3b6Chih-Chung Chang public static void closeSilently(Closeable c) { 281101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (c == null) return; 282101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin try { 283101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin c.close(); 284101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } catch (Throwable t) { 285101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // do nothing 286101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 287101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 288101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 289724e9b3db93677b753c1267a716e30e6cf5ff3b6Chih-Chung Chang public static void closeSilently(ParcelFileDescriptor c) { 290101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin if (c == null) return; 291101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin try { 292101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin c.close(); 293101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } catch (Throwable t) { 294101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin // do nothing 295101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 296101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin } 297101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin 298c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang /** 299c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang * Make a bitmap from a given Uri. 300c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang * 301c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang * @param uri 302c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang */ 303c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang public static Bitmap makeBitmap(int targetWidthOrHeight, Uri uri, 304c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang ContentResolver cr) { 305c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang ParcelFileDescriptor input = null; 306c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang try { 307c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang input = cr.openFileDescriptor(uri, "r"); 308c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang return makeBitmap(targetWidthOrHeight, uri, cr, input, null); 309c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } catch (IOException ex) { 310c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang return null; 311c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } finally { 312724e9b3db93677b753c1267a716e30e6cf5ff3b6Chih-Chung Chang closeSilently(input); 313c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 314c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 315c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang 316c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang public static Bitmap makeBitmap(int targetWidthHeight, Uri uri, 317c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang ContentResolver cr, ParcelFileDescriptor pfd, 318c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang BitmapFactory.Options options) { 319c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang Bitmap b = null; 320c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang try { 321c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang if (pfd == null) pfd = makeInputStream(uri, cr); 322c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang if (pfd == null) return null; 323c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang if (options == null) options = new BitmapFactory.Options(); 324c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang 325c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang FileDescriptor fd = pfd.getFileDescriptor(); 326c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang options.inSampleSize = 1; 327c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang if (targetWidthHeight != -1) { 328c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang options.inJustDecodeBounds = true; 329d30b5877fbdedcebc0af5cccffddccfe9b11cb0bOwen Lin BitmapManager.instance().decodeFileDescriptor(fd, options); 330c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang if (options.mCancel || options.outWidth == -1 331c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang || options.outHeight == -1) { 332c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang return null; 333c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 334c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang options.inSampleSize = 335c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang computeSampleSize(options, targetWidthHeight); 336c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang options.inJustDecodeBounds = false; 337c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 338c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang 339c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang options.inDither = false; 340c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang options.inPreferredConfig = Bitmap.Config.ARGB_8888; 341d30b5877fbdedcebc0af5cccffddccfe9b11cb0bOwen Lin b = BitmapManager.instance().decodeFileDescriptor(fd, options); 342c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } catch (OutOfMemoryError ex) { 343c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang Log.e(TAG, "Got oom exception ", ex); 344c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang return null; 345c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } finally { 346724e9b3db93677b753c1267a716e30e6cf5ff3b6Chih-Chung Chang closeSilently(pfd); 347c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 348c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang return b; 349c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 350c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang 351c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang private static ParcelFileDescriptor makeInputStream( 352c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang Uri uri, ContentResolver cr) { 353c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang try { 354c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang return cr.openFileDescriptor(uri, "r"); 355c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } catch (IOException ex) { 356c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang return null; 357c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 358c1c20e9ce386c1f660059acaede591d2d718995aChih-Chung Chang } 359fa021af9397011cf180003139e80a88902c4b70aChih-Chung Chang 360fa021af9397011cf180003139e80a88902c4b70aChih-Chung Chang public static void debugWhere(String tag, String msg) { 36174c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin Log.d(tag, msg + " --- stack trace begins: "); 36274c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin StackTraceElement elements[] = Thread.currentThread().getStackTrace(); 36374c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin // skip first 3 element, they are not related to the caller 36474c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin for (int i = 3, n = elements.length; i < n; ++i) { 36574c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin StackTraceElement st = elements[i]; 36674c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin String message = String.format(" at %s.%s(%s:%s)", 36774c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin st.getClassName(), st.getMethodName(), st.getFileName(), 36874c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin st.getLineNumber()); 36974c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin Log.d(tag, message); 37074c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin } 37174c3bd38d4155c694bbb575f389597ee60aec7d3Owen Lin Log.d(tag, msg + " --- stack trace ends."); 372fa021af9397011cf180003139e80a88902c4b70aChih-Chung Chang } 373601ce56b034f111b2875e7636776f2f359f6a156Owen Lin 374601ce56b034f111b2875e7636776f2f359f6a156Owen Lin public static <T> void showProgressDialog(final Context context, 375601ce56b034f111b2875e7636776f2f359f6a156Owen Lin String title, String message, PriorityTask<T> task) { 376601ce56b034f111b2875e7636776f2f359f6a156Owen Lin final ProgressDialog dialog = 377601ce56b034f111b2875e7636776f2f359f6a156Owen Lin ProgressDialog.show(context, title, message); 378601ce56b034f111b2875e7636776f2f359f6a156Owen Lin 379601ce56b034f111b2875e7636776f2f359f6a156Owen Lin task.addCallback(new PriorityTask.Callback<T>() { 380601ce56b034f111b2875e7636776f2f359f6a156Owen Lin 381601ce56b034f111b2875e7636776f2f359f6a156Owen Lin public void onCanceled(PriorityTask<T> t) { 382601ce56b034f111b2875e7636776f2f359f6a156Owen Lin dialog.dismiss(); 383601ce56b034f111b2875e7636776f2f359f6a156Owen Lin } 384601ce56b034f111b2875e7636776f2f359f6a156Owen Lin 385601ce56b034f111b2875e7636776f2f359f6a156Owen Lin public void onFail(PriorityTask<T> t, Throwable error) { 386601ce56b034f111b2875e7636776f2f359f6a156Owen Lin dialog.dismiss(); 387601ce56b034f111b2875e7636776f2f359f6a156Owen Lin } 388601ce56b034f111b2875e7636776f2f359f6a156Owen Lin 389601ce56b034f111b2875e7636776f2f359f6a156Owen Lin public void onResultAvailable(PriorityTask<T> t, T result) { 390601ce56b034f111b2875e7636776f2f359f6a156Owen Lin dialog.dismiss(); 391601ce56b034f111b2875e7636776f2f359f6a156Owen Lin } 392601ce56b034f111b2875e7636776f2f359f6a156Owen Lin }); 393601ce56b034f111b2875e7636776f2f359f6a156Owen Lin } 394601ce56b034f111b2875e7636776f2f359f6a156Owen Lin 3954177add422a041ea9f1007c05ff42361bf529d52Chih-Chung Chang public static synchronized OnClickListener getNullOnClickListener() { 396601ce56b034f111b2875e7636776f2f359f6a156Owen Lin if (sNullOnClickListener == null) { 397601ce56b034f111b2875e7636776f2f359f6a156Owen Lin sNullOnClickListener = new OnClickListener() { 398601ce56b034f111b2875e7636776f2f359f6a156Owen Lin public void onClick(View v) { 399601ce56b034f111b2875e7636776f2f359f6a156Owen Lin } 400601ce56b034f111b2875e7636776f2f359f6a156Owen Lin }; 401601ce56b034f111b2875e7636776f2f359f6a156Owen Lin } 402601ce56b034f111b2875e7636776f2f359f6a156Owen Lin return sNullOnClickListener; 403601ce56b034f111b2875e7636776f2f359f6a156Owen Lin } 404341ad98e59d92769e1cc8ba68fa86c72dce0543bChih-Chung Chang 405341ad98e59d92769e1cc8ba68fa86c72dce0543bChih-Chung Chang public static void Assert(boolean cond) { 406341ad98e59d92769e1cc8ba68fa86c72dce0543bChih-Chung Chang if (!cond) { 407341ad98e59d92769e1cc8ba68fa86c72dce0543bChih-Chung Chang throw new AssertionError(); 408341ad98e59d92769e1cc8ba68fa86c72dce0543bChih-Chung Chang } 409341ad98e59d92769e1cc8ba68fa86c72dce0543bChih-Chung Chang } 410059daa36dc6e83ca24a16d9b99925e71010bccebOwen Lin 411b0e1282810ec68fd7585beb9ab9afab9bcafe1bdOwen Lin public static boolean equals(String a, String b) { 412b0e1282810ec68fd7585beb9ab9afab9bcafe1bdOwen Lin // return true if both string are null or the content equals 413b0e1282810ec68fd7585beb9ab9afab9bcafe1bdOwen Lin return a == b || a.equals(b); 414b0e1282810ec68fd7585beb9ab9afab9bcafe1bdOwen Lin } 415482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin 416482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin private static class BackgroundJob 417482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin extends MonitoredActivity.LifeCycleAdapter implements Runnable { 418482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin 419482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin private final MonitoredActivity mActivity; 420482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin private final ProgressDialog mDialog; 421482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin private final Runnable mJob; 422482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin private final Handler mHandler; 4236fa5404fd6c34d401c56accd059a706d8a832812Owen Lin private final Runnable mCleanupRunner = new Runnable() { 4246fa5404fd6c34d401c56accd059a706d8a832812Owen Lin public void run() { 4256fa5404fd6c34d401c56accd059a706d8a832812Owen Lin mActivity.removeLifeCycleListener(BackgroundJob.this); 4266fa5404fd6c34d401c56accd059a706d8a832812Owen Lin if (mDialog.getWindow() != null) mDialog.dismiss(); 4276fa5404fd6c34d401c56accd059a706d8a832812Owen Lin } 4286fa5404fd6c34d401c56accd059a706d8a832812Owen Lin }; 429482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin 430482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin public BackgroundJob(MonitoredActivity activity, Runnable job, 431482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin ProgressDialog dialog, Handler handler) { 432482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mActivity = activity; 433482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mDialog = dialog; 434482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mJob = job; 435482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mActivity.addLifeCycleListener(this); 436482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mHandler = handler; 437482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } 438482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin 439482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin public void run() { 440482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin try { 441482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mJob.run(); 442482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } finally { 4436fa5404fd6c34d401c56accd059a706d8a832812Owen Lin mHandler.post(mCleanupRunner); 444482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } 445482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } 446482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin 4476fa5404fd6c34d401c56accd059a706d8a832812Owen Lin 4486fa5404fd6c34d401c56accd059a706d8a832812Owen Lin @Override 4496fa5404fd6c34d401c56accd059a706d8a832812Owen Lin public void onActivityDestroyed(MonitoredActivity activity) { 4506fa5404fd6c34d401c56accd059a706d8a832812Owen Lin // We get here only when the onDestroyed being called before 4516fa5404fd6c34d401c56accd059a706d8a832812Owen Lin // the mCleanupRunner. So, run it now and remove it from the queue 4526fa5404fd6c34d401c56accd059a706d8a832812Owen Lin mCleanupRunner.run(); 4536fa5404fd6c34d401c56accd059a706d8a832812Owen Lin mHandler.removeCallbacks(mCleanupRunner); 4546fa5404fd6c34d401c56accd059a706d8a832812Owen Lin } 4556fa5404fd6c34d401c56accd059a706d8a832812Owen Lin 456482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin @Override 457482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin public void onActivityStopped(MonitoredActivity activity) { 458482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mDialog.hide(); 459482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } 460482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin 461482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin @Override 462482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin public void onActivityStarted(MonitoredActivity activity) { 463482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin mDialog.show(); 464482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } 465482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } 466482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin 467482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin public static void startBackgroundJob(MonitoredActivity activity, 468482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin String title, String message, Runnable job, Handler handler) { 469482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin // Make the progress dialog uncancelable, so that we can gurantee 470482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin // the thread will be done before the activity getting destroyed. 471482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin ProgressDialog dialog = ProgressDialog.show( 472482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin activity, title, message, true, false); 473482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin new Thread(new BackgroundJob(activity, job, dialog, handler)).start(); 474482a3a54cfa8ec2cc913efc0e73a01d78453ee6dOwen Lin } 475bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang 476bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang // Returns an intent which is used for "set as" menu items. 477bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang public static Intent createSetAsIntent(IImage image) { 478bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang Uri u = image.fullSizeImageUri(); 479bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang Intent intent = new Intent(Intent.ACTION_ATTACH_DATA); 480bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang intent.setDataAndType(u, image.getMimeType()); 481bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang intent.putExtra("mimeType", image.getMimeType()); 482bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang return intent; 483bb1877847ae050918fe591d9b7fa63deaf645746Chih-Chung Chang } 484d5d74642d7c0b43578b43cdd46b70671b64c88e2Wei-Ta Chen 485d5d74642d7c0b43578b43cdd46b70671b64c88e2Wei-Ta Chen // Returns Options that set the puregeable flag for Bitmap decode. 486026dff889c80763fc322ed03e2d3a76750320138Wei-Ta Chen public static BitmapFactory.Options createNativeAllocOptions() { 487d5d74642d7c0b43578b43cdd46b70671b64c88e2Wei-Ta Chen BitmapFactory.Options options = new BitmapFactory.Options(); 488026dff889c80763fc322ed03e2d3a76750320138Wei-Ta Chen options.inNativeAlloc = true; 489d5d74642d7c0b43578b43cdd46b70671b64c88e2Wei-Ta Chen return options; 490d5d74642d7c0b43578b43cdd46b70671b64c88e2Wei-Ta Chen } 491101d528d59f447847d5c6b7578642132c2b76f4fOwen Lin} 492