1666ea1b28a76aeba74744148b15099254d918671Owen Lin/* 2666ea1b28a76aeba74744148b15099254d918671Owen Lin * Copyright (C) 2007 The Android Open Source Project 3666ea1b28a76aeba74744148b15099254d918671Owen Lin * 4666ea1b28a76aeba74744148b15099254d918671Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5666ea1b28a76aeba74744148b15099254d918671Owen Lin * you may not use this file except in compliance with the License. 6666ea1b28a76aeba74744148b15099254d918671Owen Lin * You may obtain a copy of the License at 7666ea1b28a76aeba74744148b15099254d918671Owen Lin * 8666ea1b28a76aeba74744148b15099254d918671Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9666ea1b28a76aeba74744148b15099254d918671Owen Lin * 10666ea1b28a76aeba74744148b15099254d918671Owen Lin * Unless required by applicable law or agreed to in writing, software 11666ea1b28a76aeba74744148b15099254d918671Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12666ea1b28a76aeba74744148b15099254d918671Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13666ea1b28a76aeba74744148b15099254d918671Owen Lin * See the License for the specific language governing permissions and 14666ea1b28a76aeba74744148b15099254d918671Owen Lin * limitations under the License. 15666ea1b28a76aeba74744148b15099254d918671Owen Lin */ 16666ea1b28a76aeba74744148b15099254d918671Owen Lin 17666ea1b28a76aeba74744148b15099254d918671Owen Linpackage com.android.camera; 18666ea1b28a76aeba74744148b15099254d918671Owen Lin 19d6c2fb7a38fcdb58742fcfffd67a4594487ec71cOwen Linimport com.android.gallery.R; 20d6c2fb7a38fcdb58742fcfffd67a4594487ec71cOwen Lin 21666ea1b28a76aeba74744148b15099254d918671Owen Linimport com.android.camera.gallery.IImage; 22666ea1b28a76aeba74744148b15099254d918671Owen Linimport com.android.camera.gallery.IImageList; 23666ea1b28a76aeba74744148b15099254d918671Owen Lin 24666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.app.Activity; 25666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.app.Dialog; 26666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.app.ProgressDialog; 27666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.BroadcastReceiver; 28666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.ContentResolver; 29666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.Context; 30666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.Intent; 31666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.IntentFilter; 32666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.content.res.Resources; 33666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.database.ContentObserver; 34666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.Bitmap; 35666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.Canvas; 36666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.Matrix; 37666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.Paint; 38666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.PorterDuff; 39666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.PorterDuffXfermode; 40666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.Rect; 41666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.graphics.drawable.Drawable; 42666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.net.Uri; 43666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.Bundle; 44666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.Environment; 45666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.Handler; 46666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.os.StatFs; 47666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.provider.MediaStore; 48666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.provider.MediaStore.Images; 49666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.util.Log; 50666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.ContextMenu; 51666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.LayoutInflater; 52666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.Menu; 53666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.MenuItem; 54666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.View; 55666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.ViewGroup; 56666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.ContextMenu.ContextMenuInfo; 57666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.view.MenuItem.OnMenuItemClickListener; 58666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.AdapterView; 59666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.BaseAdapter; 60666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.GridView; 61666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.TextView; 62666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.Toast; 63666ea1b28a76aeba74744148b15099254d918671Owen Linimport android.widget.AdapterView.AdapterContextMenuInfo; 64666ea1b28a76aeba74744148b15099254d918671Owen Lin 65666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.util.ArrayList; 66666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.util.HashMap; 67666ea1b28a76aeba74744148b15099254d918671Owen Linimport java.util.Map; 68666ea1b28a76aeba74744148b15099254d918671Owen Lin 69666ea1b28a76aeba74744148b15099254d918671Owen Lin/** 70666ea1b28a76aeba74744148b15099254d918671Owen Lin * The GalleryPicker activity. 71666ea1b28a76aeba74744148b15099254d918671Owen Lin */ 728aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Linpublic class GalleryPicker extends NoSearchActivity { 73666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final String TAG = "GalleryPicker"; 74666ea1b28a76aeba74744148b15099254d918671Owen Lin 75666ea1b28a76aeba74744148b15099254d918671Owen Lin Handler mHandler = new Handler(); // handler for the main thread 76666ea1b28a76aeba74744148b15099254d918671Owen Lin Thread mWorkerThread; 77666ea1b28a76aeba74744148b15099254d918671Owen Lin BroadcastReceiver mReceiver; 78666ea1b28a76aeba74744148b15099254d918671Owen Lin ContentObserver mDbObserver; 79666ea1b28a76aeba74744148b15099254d918671Owen Lin GridView mGridView; 80666ea1b28a76aeba74744148b15099254d918671Owen Lin GalleryPickerAdapter mAdapter; // mAdapter is only accessed in main thread. 81666ea1b28a76aeba74744148b15099254d918671Owen Lin boolean mScanning; 82666ea1b28a76aeba74744148b15099254d918671Owen Lin boolean mUnmounted; 83666ea1b28a76aeba74744148b15099254d918671Owen Lin 84666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 85666ea1b28a76aeba74744148b15099254d918671Owen Lin public void onCreate(Bundle icicle) { 86666ea1b28a76aeba74744148b15099254d918671Owen Lin super.onCreate(icicle); 87666ea1b28a76aeba74744148b15099254d918671Owen Lin 88666ea1b28a76aeba74744148b15099254d918671Owen Lin setContentView(R.layout.gallerypicker); 89666ea1b28a76aeba74744148b15099254d918671Owen Lin 90666ea1b28a76aeba74744148b15099254d918671Owen Lin mGridView = (GridView) findViewById(R.id.albums); 91666ea1b28a76aeba74744148b15099254d918671Owen Lin 92666ea1b28a76aeba74744148b15099254d918671Owen Lin mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 93666ea1b28a76aeba74744148b15099254d918671Owen Lin public void onItemClick(AdapterView<?> parent, View view, 94666ea1b28a76aeba74744148b15099254d918671Owen Lin int position, long id) { 95666ea1b28a76aeba74744148b15099254d918671Owen Lin launchFolderGallery(position); 96666ea1b28a76aeba74744148b15099254d918671Owen Lin } 97666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 98666ea1b28a76aeba74744148b15099254d918671Owen Lin 99666ea1b28a76aeba74744148b15099254d918671Owen Lin mGridView.setOnCreateContextMenuListener( 100666ea1b28a76aeba74744148b15099254d918671Owen Lin new View.OnCreateContextMenuListener() { 101666ea1b28a76aeba74744148b15099254d918671Owen Lin public void onCreateContextMenu(ContextMenu menu, View v, 102666ea1b28a76aeba74744148b15099254d918671Owen Lin final ContextMenuInfo menuInfo) { 103666ea1b28a76aeba74744148b15099254d918671Owen Lin onCreateGalleryPickerContextMenu(menu, menuInfo); 104666ea1b28a76aeba74744148b15099254d918671Owen Lin } 105666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 106666ea1b28a76aeba74744148b15099254d918671Owen Lin 107666ea1b28a76aeba74744148b15099254d918671Owen Lin mReceiver = new BroadcastReceiver() { 108666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 109666ea1b28a76aeba74744148b15099254d918671Owen Lin public void onReceive(Context context, Intent intent) { 110666ea1b28a76aeba74744148b15099254d918671Owen Lin onReceiveMediaBroadcast(intent); 111666ea1b28a76aeba74744148b15099254d918671Owen Lin } 112666ea1b28a76aeba74744148b15099254d918671Owen Lin }; 113666ea1b28a76aeba74744148b15099254d918671Owen Lin 114666ea1b28a76aeba74744148b15099254d918671Owen Lin mDbObserver = new ContentObserver(mHandler) { 115666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 116666ea1b28a76aeba74744148b15099254d918671Owen Lin public void onChange(boolean selfChange) { 117666ea1b28a76aeba74744148b15099254d918671Owen Lin rebake(false, ImageManager.isMediaScannerScanning( 118666ea1b28a76aeba74744148b15099254d918671Owen Lin getContentResolver())); 119666ea1b28a76aeba74744148b15099254d918671Owen Lin } 120666ea1b28a76aeba74744148b15099254d918671Owen Lin }; 121666ea1b28a76aeba74744148b15099254d918671Owen Lin 122666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.ensureOSXCompatibleFolder(); 123666ea1b28a76aeba74744148b15099254d918671Owen Lin } 124666ea1b28a76aeba74744148b15099254d918671Owen Lin 125666ea1b28a76aeba74744148b15099254d918671Owen Lin Dialog mMediaScanningDialog; 126666ea1b28a76aeba74744148b15099254d918671Owen Lin 127666ea1b28a76aeba74744148b15099254d918671Owen Lin // Display a dialog if the storage is being scanned now. 128666ea1b28a76aeba74744148b15099254d918671Owen Lin public void updateScanningDialog(boolean scanning) { 129666ea1b28a76aeba74744148b15099254d918671Owen Lin boolean prevScanning = (mMediaScanningDialog != null); 130666ea1b28a76aeba74744148b15099254d918671Owen Lin if (prevScanning == scanning && mAdapter.mItems.size() == 0) return; 131666ea1b28a76aeba74744148b15099254d918671Owen Lin // Now we are certain the state is changed. 132666ea1b28a76aeba74744148b15099254d918671Owen Lin if (prevScanning) { 133666ea1b28a76aeba74744148b15099254d918671Owen Lin mMediaScanningDialog.cancel(); 134666ea1b28a76aeba74744148b15099254d918671Owen Lin mMediaScanningDialog = null; 135666ea1b28a76aeba74744148b15099254d918671Owen Lin } else if (scanning && mAdapter.mItems.size() == 0) { 136666ea1b28a76aeba74744148b15099254d918671Owen Lin mMediaScanningDialog = ProgressDialog.show( 137666ea1b28a76aeba74744148b15099254d918671Owen Lin this, 138666ea1b28a76aeba74744148b15099254d918671Owen Lin null, 139666ea1b28a76aeba74744148b15099254d918671Owen Lin getResources().getString(R.string.wait), 140666ea1b28a76aeba74744148b15099254d918671Owen Lin true, 141666ea1b28a76aeba74744148b15099254d918671Owen Lin true); 142666ea1b28a76aeba74744148b15099254d918671Owen Lin } 143666ea1b28a76aeba74744148b15099254d918671Owen Lin } 144666ea1b28a76aeba74744148b15099254d918671Owen Lin 145666ea1b28a76aeba74744148b15099254d918671Owen Lin private View mNoImagesView; 146666ea1b28a76aeba74744148b15099254d918671Owen Lin 147666ea1b28a76aeba74744148b15099254d918671Owen Lin // Show/Hide the "no images" icon and text. Load resources on demand. 148666ea1b28a76aeba74744148b15099254d918671Owen Lin private void showNoImagesView() { 149666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mNoImagesView == null) { 150666ea1b28a76aeba74744148b15099254d918671Owen Lin ViewGroup root = (ViewGroup) findViewById(R.id.root); 151666ea1b28a76aeba74744148b15099254d918671Owen Lin getLayoutInflater().inflate(R.layout.gallerypicker_no_images, root); 152666ea1b28a76aeba74744148b15099254d918671Owen Lin mNoImagesView = findViewById(R.id.no_images); 153666ea1b28a76aeba74744148b15099254d918671Owen Lin } 154666ea1b28a76aeba74744148b15099254d918671Owen Lin mNoImagesView.setVisibility(View.VISIBLE); 155666ea1b28a76aeba74744148b15099254d918671Owen Lin } 156666ea1b28a76aeba74744148b15099254d918671Owen Lin 157666ea1b28a76aeba74744148b15099254d918671Owen Lin private void hideNoImagesView() { 158666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mNoImagesView != null) { 159666ea1b28a76aeba74744148b15099254d918671Owen Lin mNoImagesView.setVisibility(View.GONE); 160666ea1b28a76aeba74744148b15099254d918671Owen Lin } 161666ea1b28a76aeba74744148b15099254d918671Owen Lin } 162666ea1b28a76aeba74744148b15099254d918671Owen Lin 163666ea1b28a76aeba74744148b15099254d918671Owen Lin // The storage status is changed, restart the worker or show "no images". 164666ea1b28a76aeba74744148b15099254d918671Owen Lin private void rebake(boolean unmounted, boolean scanning) { 165666ea1b28a76aeba74744148b15099254d918671Owen Lin if (unmounted == mUnmounted && scanning == mScanning) return; 166666ea1b28a76aeba74744148b15099254d918671Owen Lin abortWorker(); 167666ea1b28a76aeba74744148b15099254d918671Owen Lin mUnmounted = unmounted; 168666ea1b28a76aeba74744148b15099254d918671Owen Lin mScanning = scanning; 169666ea1b28a76aeba74744148b15099254d918671Owen Lin updateScanningDialog(mScanning); 170666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mUnmounted) { 171666ea1b28a76aeba74744148b15099254d918671Owen Lin showNoImagesView(); 172666ea1b28a76aeba74744148b15099254d918671Owen Lin } else { 173666ea1b28a76aeba74744148b15099254d918671Owen Lin hideNoImagesView(); 174666ea1b28a76aeba74744148b15099254d918671Owen Lin startWorker(); 175666ea1b28a76aeba74744148b15099254d918671Owen Lin } 176666ea1b28a76aeba74744148b15099254d918671Owen Lin } 177666ea1b28a76aeba74744148b15099254d918671Owen Lin 178666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is called when we receive media-related broadcast. 179666ea1b28a76aeba74744148b15099254d918671Owen Lin private void onReceiveMediaBroadcast(Intent intent) { 180666ea1b28a76aeba74744148b15099254d918671Owen Lin String action = intent.getAction(); 181666ea1b28a76aeba74744148b15099254d918671Owen Lin if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) { 182666ea1b28a76aeba74744148b15099254d918671Owen Lin // SD card available 183666ea1b28a76aeba74744148b15099254d918671Owen Lin // TODO put up a "please wait" message 184666ea1b28a76aeba74744148b15099254d918671Owen Lin } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { 185666ea1b28a76aeba74744148b15099254d918671Owen Lin // SD card unavailable 186666ea1b28a76aeba74744148b15099254d918671Owen Lin rebake(true, false); 187666ea1b28a76aeba74744148b15099254d918671Owen Lin } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) { 188666ea1b28a76aeba74744148b15099254d918671Owen Lin rebake(false, true); 189666ea1b28a76aeba74744148b15099254d918671Owen Lin } else if (action.equals( 190666ea1b28a76aeba74744148b15099254d918671Owen Lin Intent.ACTION_MEDIA_SCANNER_FINISHED)) { 191666ea1b28a76aeba74744148b15099254d918671Owen Lin rebake(false, false); 192666ea1b28a76aeba74744148b15099254d918671Owen Lin } else if (action.equals(Intent.ACTION_MEDIA_EJECT)) { 193666ea1b28a76aeba74744148b15099254d918671Owen Lin rebake(true, false); 194666ea1b28a76aeba74744148b15099254d918671Owen Lin } 195666ea1b28a76aeba74744148b15099254d918671Owen Lin } 196666ea1b28a76aeba74744148b15099254d918671Owen Lin 197666ea1b28a76aeba74744148b15099254d918671Owen Lin private void launchFolderGallery(int position) { 198666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter.mItems.get(position).launch(this); 199666ea1b28a76aeba74744148b15099254d918671Owen Lin } 200666ea1b28a76aeba74744148b15099254d918671Owen Lin 201666ea1b28a76aeba74744148b15099254d918671Owen Lin private void onCreateGalleryPickerContextMenu(ContextMenu menu, 202666ea1b28a76aeba74744148b15099254d918671Owen Lin final ContextMenuInfo menuInfo) { 203666ea1b28a76aeba74744148b15099254d918671Owen Lin int position = ((AdapterContextMenuInfo) menuInfo).position; 204666ea1b28a76aeba74744148b15099254d918671Owen Lin menu.setHeaderTitle(mAdapter.baseTitleForPosition(position)); 205666ea1b28a76aeba74744148b15099254d918671Owen Lin // "Slide Show" 206666ea1b28a76aeba74744148b15099254d918671Owen Lin if ((mAdapter.getIncludeMediaTypes(position) 207666ea1b28a76aeba74744148b15099254d918671Owen Lin & ImageManager.INCLUDE_IMAGES) != 0) { 208666ea1b28a76aeba74744148b15099254d918671Owen Lin menu.add(R.string.slide_show) 209666ea1b28a76aeba74744148b15099254d918671Owen Lin .setOnMenuItemClickListener(new OnMenuItemClickListener() { 210666ea1b28a76aeba74744148b15099254d918671Owen Lin public boolean onMenuItemClick(MenuItem item) { 211666ea1b28a76aeba74744148b15099254d918671Owen Lin return onSlideShowClicked(menuInfo); 212666ea1b28a76aeba74744148b15099254d918671Owen Lin } 213666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 214666ea1b28a76aeba74744148b15099254d918671Owen Lin } 215666ea1b28a76aeba74744148b15099254d918671Owen Lin // "View" 216666ea1b28a76aeba74744148b15099254d918671Owen Lin menu.add(R.string.view) 217666ea1b28a76aeba74744148b15099254d918671Owen Lin .setOnMenuItemClickListener(new OnMenuItemClickListener() { 218666ea1b28a76aeba74744148b15099254d918671Owen Lin public boolean onMenuItemClick(MenuItem item) { 219666ea1b28a76aeba74744148b15099254d918671Owen Lin return onViewClicked(menuInfo); 220666ea1b28a76aeba74744148b15099254d918671Owen Lin } 221666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 222666ea1b28a76aeba74744148b15099254d918671Owen Lin } 223666ea1b28a76aeba74744148b15099254d918671Owen Lin 224666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is called when the user clicks "Slideshow" from the context menu. 225666ea1b28a76aeba74744148b15099254d918671Owen Lin private boolean onSlideShowClicked(ContextMenuInfo menuInfo) { 226666ea1b28a76aeba74744148b15099254d918671Owen Lin AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; 227666ea1b28a76aeba74744148b15099254d918671Owen Lin int position = info.position; 228666ea1b28a76aeba74744148b15099254d918671Owen Lin 229666ea1b28a76aeba74744148b15099254d918671Owen Lin if (position < 0 || position >= mAdapter.mItems.size()) { 230666ea1b28a76aeba74744148b15099254d918671Owen Lin return true; 231666ea1b28a76aeba74744148b15099254d918671Owen Lin } 232666ea1b28a76aeba74744148b15099254d918671Owen Lin // Slide show starts from the first image on the list. 233666ea1b28a76aeba74744148b15099254d918671Owen Lin Item item = mAdapter.mItems.get(position); 234666ea1b28a76aeba74744148b15099254d918671Owen Lin Uri targetUri = item.mFirstImageUri; 235666ea1b28a76aeba74744148b15099254d918671Owen Lin 236666ea1b28a76aeba74744148b15099254d918671Owen Lin if (targetUri != null && item.mBucketId != null) { 237666ea1b28a76aeba74744148b15099254d918671Owen Lin targetUri = targetUri.buildUpon() 238666ea1b28a76aeba74744148b15099254d918671Owen Lin .appendQueryParameter("bucketId", item.mBucketId) 239666ea1b28a76aeba74744148b15099254d918671Owen Lin .build(); 240666ea1b28a76aeba74744148b15099254d918671Owen Lin } 241666ea1b28a76aeba74744148b15099254d918671Owen Lin Intent intent = new Intent(Intent.ACTION_VIEW, targetUri); 242666ea1b28a76aeba74744148b15099254d918671Owen Lin intent.putExtra("slideshow", true); 243666ea1b28a76aeba74744148b15099254d918671Owen Lin startActivity(intent); 244666ea1b28a76aeba74744148b15099254d918671Owen Lin return true; 245666ea1b28a76aeba74744148b15099254d918671Owen Lin } 246666ea1b28a76aeba74744148b15099254d918671Owen Lin 247666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is called when the user clicks "View" from the context menu. 248666ea1b28a76aeba74744148b15099254d918671Owen Lin private boolean onViewClicked(ContextMenuInfo menuInfo) { 249666ea1b28a76aeba74744148b15099254d918671Owen Lin AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo; 250666ea1b28a76aeba74744148b15099254d918671Owen Lin launchFolderGallery(info.position); 251666ea1b28a76aeba74744148b15099254d918671Owen Lin return true; 252666ea1b28a76aeba74744148b15099254d918671Owen Lin } 253666ea1b28a76aeba74744148b15099254d918671Owen Lin 254666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 255666ea1b28a76aeba74744148b15099254d918671Owen Lin public void onStop() { 256666ea1b28a76aeba74744148b15099254d918671Owen Lin super.onStop(); 257666ea1b28a76aeba74744148b15099254d918671Owen Lin 258666ea1b28a76aeba74744148b15099254d918671Owen Lin abortWorker(); 259666ea1b28a76aeba74744148b15099254d918671Owen Lin 260666ea1b28a76aeba74744148b15099254d918671Owen Lin unregisterReceiver(mReceiver); 261666ea1b28a76aeba74744148b15099254d918671Owen Lin getContentResolver().unregisterContentObserver(mDbObserver); 262666ea1b28a76aeba74744148b15099254d918671Owen Lin 263666ea1b28a76aeba74744148b15099254d918671Owen Lin // free up some ram 264666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter = null; 265666ea1b28a76aeba74744148b15099254d918671Owen Lin mGridView.setAdapter(null); 266666ea1b28a76aeba74744148b15099254d918671Owen Lin unloadDrawable(); 267666ea1b28a76aeba74744148b15099254d918671Owen Lin } 268666ea1b28a76aeba74744148b15099254d918671Owen Lin 269666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 270666ea1b28a76aeba74744148b15099254d918671Owen Lin public void onStart() { 271666ea1b28a76aeba74744148b15099254d918671Owen Lin super.onStart(); 272666ea1b28a76aeba74744148b15099254d918671Owen Lin 273666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter = new GalleryPickerAdapter(getLayoutInflater()); 274666ea1b28a76aeba74744148b15099254d918671Owen Lin mGridView.setAdapter(mAdapter); 275666ea1b28a76aeba74744148b15099254d918671Owen Lin 276666ea1b28a76aeba74744148b15099254d918671Owen Lin // install an intent filter to receive SD card related events. 277666ea1b28a76aeba74744148b15099254d918671Owen Lin IntentFilter intentFilter = new IntentFilter(); 278666ea1b28a76aeba74744148b15099254d918671Owen Lin intentFilter.addAction(Intent.ACTION_MEDIA_MOUNTED); 279666ea1b28a76aeba74744148b15099254d918671Owen Lin intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); 280666ea1b28a76aeba74744148b15099254d918671Owen Lin intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); 281666ea1b28a76aeba74744148b15099254d918671Owen Lin intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED); 282666ea1b28a76aeba74744148b15099254d918671Owen Lin intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); 283666ea1b28a76aeba74744148b15099254d918671Owen Lin intentFilter.addDataScheme("file"); 284666ea1b28a76aeba74744148b15099254d918671Owen Lin 285666ea1b28a76aeba74744148b15099254d918671Owen Lin registerReceiver(mReceiver, intentFilter); 286666ea1b28a76aeba74744148b15099254d918671Owen Lin 287666ea1b28a76aeba74744148b15099254d918671Owen Lin getContentResolver().registerContentObserver( 288666ea1b28a76aeba74744148b15099254d918671Owen Lin MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 289666ea1b28a76aeba74744148b15099254d918671Owen Lin true, mDbObserver); 290666ea1b28a76aeba74744148b15099254d918671Owen Lin 291666ea1b28a76aeba74744148b15099254d918671Owen Lin // Assume the storage is mounted and not scanning. 292666ea1b28a76aeba74744148b15099254d918671Owen Lin mUnmounted = false; 293666ea1b28a76aeba74744148b15099254d918671Owen Lin mScanning = false; 294666ea1b28a76aeba74744148b15099254d918671Owen Lin startWorker(); 295666ea1b28a76aeba74744148b15099254d918671Owen Lin } 296666ea1b28a76aeba74744148b15099254d918671Owen Lin 297666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is used to stop the worker thread. 298666ea1b28a76aeba74744148b15099254d918671Owen Lin volatile boolean mAbort = false; 299666ea1b28a76aeba74744148b15099254d918671Owen Lin 300666ea1b28a76aeba74744148b15099254d918671Owen Lin // Create the worker thread. 301666ea1b28a76aeba74744148b15099254d918671Owen Lin private void startWorker() { 302666ea1b28a76aeba74744148b15099254d918671Owen Lin mAbort = false; 303666ea1b28a76aeba74744148b15099254d918671Owen Lin mWorkerThread = new Thread("GalleryPicker Worker") { 304666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 305666ea1b28a76aeba74744148b15099254d918671Owen Lin public void run() { 306666ea1b28a76aeba74744148b15099254d918671Owen Lin workerRun(); 307666ea1b28a76aeba74744148b15099254d918671Owen Lin } 308666ea1b28a76aeba74744148b15099254d918671Owen Lin }; 309666ea1b28a76aeba74744148b15099254d918671Owen Lin BitmapManager.instance().allowThreadDecoding(mWorkerThread); 310666ea1b28a76aeba74744148b15099254d918671Owen Lin mWorkerThread.start(); 311666ea1b28a76aeba74744148b15099254d918671Owen Lin } 312666ea1b28a76aeba74744148b15099254d918671Owen Lin 313666ea1b28a76aeba74744148b15099254d918671Owen Lin private void abortWorker() { 314666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mWorkerThread != null) { 3158aa3fbcf9a5a0d11acd48861f5167073e3554980Owen Lin BitmapManager.instance().cancelThreadDecoding(mWorkerThread, getContentResolver()); 316666ea1b28a76aeba74744148b15099254d918671Owen Lin mAbort = true; 317666ea1b28a76aeba74744148b15099254d918671Owen Lin try { 318666ea1b28a76aeba74744148b15099254d918671Owen Lin mWorkerThread.join(); 319666ea1b28a76aeba74744148b15099254d918671Owen Lin } catch (InterruptedException ex) { 320666ea1b28a76aeba74744148b15099254d918671Owen Lin Log.e(TAG, "join interrupted"); 321666ea1b28a76aeba74744148b15099254d918671Owen Lin } 322666ea1b28a76aeba74744148b15099254d918671Owen Lin mWorkerThread = null; 323666ea1b28a76aeba74744148b15099254d918671Owen Lin // Remove all runnables in mHandler. 324666ea1b28a76aeba74744148b15099254d918671Owen Lin // (We assume that the "what" field in the messages are 0 325666ea1b28a76aeba74744148b15099254d918671Owen Lin // for runnables). 326666ea1b28a76aeba74744148b15099254d918671Owen Lin mHandler.removeMessages(0); 327666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter.clear(); 328666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter.updateDisplay(); 329666ea1b28a76aeba74744148b15099254d918671Owen Lin clearImageLists(); 330666ea1b28a76aeba74744148b15099254d918671Owen Lin } 331666ea1b28a76aeba74744148b15099254d918671Owen Lin } 332666ea1b28a76aeba74744148b15099254d918671Owen Lin 333666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the worker thread. 334666ea1b28a76aeba74744148b15099254d918671Owen Lin private void workerRun() { 335666ea1b28a76aeba74744148b15099254d918671Owen Lin // We collect items from checkImageList() and checkBucketIds() and 336666ea1b28a76aeba74744148b15099254d918671Owen Lin // put them in allItems. Later we give allItems to checkThumbBitmap() 337666ea1b28a76aeba74744148b15099254d918671Owen Lin // and generated thumbnail bitmaps for each item. We do this instead of 338666ea1b28a76aeba74744148b15099254d918671Owen Lin // generating thumbnail bitmaps in checkImageList() and checkBucketIds() 339666ea1b28a76aeba74744148b15099254d918671Owen Lin // because we want to show all the folders first, then update them with 340666ea1b28a76aeba74744148b15099254d918671Owen Lin // the thumb bitmaps. (Generating thumbnail bitmaps takes some time.) 341666ea1b28a76aeba74744148b15099254d918671Owen Lin ArrayList<Item> allItems = new ArrayList<Item>(); 342666ea1b28a76aeba74744148b15099254d918671Owen Lin 343666ea1b28a76aeba74744148b15099254d918671Owen Lin checkScanning(); 344666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) return; 345666ea1b28a76aeba74744148b15099254d918671Owen Lin 346666ea1b28a76aeba74744148b15099254d918671Owen Lin checkImageList(allItems); 347666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) return; 348666ea1b28a76aeba74744148b15099254d918671Owen Lin 349666ea1b28a76aeba74744148b15099254d918671Owen Lin checkBucketIds(allItems); 350666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) return; 351666ea1b28a76aeba74744148b15099254d918671Owen Lin 352666ea1b28a76aeba74744148b15099254d918671Owen Lin checkThumbBitmap(allItems); 353666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) return; 354666ea1b28a76aeba74744148b15099254d918671Owen Lin 355666ea1b28a76aeba74744148b15099254d918671Owen Lin checkLowStorage(); 356666ea1b28a76aeba74744148b15099254d918671Owen Lin } 357666ea1b28a76aeba74744148b15099254d918671Owen Lin 358666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the worker thread. 359666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkScanning() { 360666ea1b28a76aeba74744148b15099254d918671Owen Lin ContentResolver cr = getContentResolver(); 361666ea1b28a76aeba74744148b15099254d918671Owen Lin final boolean scanning = 362666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.isMediaScannerScanning(cr); 363666ea1b28a76aeba74744148b15099254d918671Owen Lin mHandler.post(new Runnable() { 364666ea1b28a76aeba74744148b15099254d918671Owen Lin public void run() { 365666ea1b28a76aeba74744148b15099254d918671Owen Lin checkScanningFinished(scanning); 366666ea1b28a76aeba74744148b15099254d918671Owen Lin } 367666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 368666ea1b28a76aeba74744148b15099254d918671Owen Lin } 369666ea1b28a76aeba74744148b15099254d918671Owen Lin 370666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the main thread. 371666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkScanningFinished(boolean scanning) { 372666ea1b28a76aeba74744148b15099254d918671Owen Lin updateScanningDialog(scanning); 373666ea1b28a76aeba74744148b15099254d918671Owen Lin } 374666ea1b28a76aeba74744148b15099254d918671Owen Lin 375666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the worker thread. 376666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkImageList(ArrayList<Item> allItems) { 377666ea1b28a76aeba74744148b15099254d918671Owen Lin int length = IMAGE_LIST_DATA.length; 378666ea1b28a76aeba74744148b15099254d918671Owen Lin IImageList[] lists = new IImageList[length]; 379666ea1b28a76aeba74744148b15099254d918671Owen Lin for (int i = 0; i < length; i++) { 380666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageListData data = IMAGE_LIST_DATA[i]; 381666ea1b28a76aeba74744148b15099254d918671Owen Lin lists[i] = createImageList(data.mInclude, data.mBucketId, 382666ea1b28a76aeba74744148b15099254d918671Owen Lin getContentResolver()); 383666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) return; 384666ea1b28a76aeba74744148b15099254d918671Owen Lin Item item = null; 385666ea1b28a76aeba74744148b15099254d918671Owen Lin 386666ea1b28a76aeba74744148b15099254d918671Owen Lin if (lists[i].isEmpty()) continue; 387666ea1b28a76aeba74744148b15099254d918671Owen Lin 388666ea1b28a76aeba74744148b15099254d918671Owen Lin // i >= 3 means we are looking at All Images/All Videos. 389666ea1b28a76aeba74744148b15099254d918671Owen Lin // lists[i-3] is the corresponding Camera Images/Camera Videos. 390666ea1b28a76aeba74744148b15099254d918671Owen Lin // We want to add the "All" list only if it's different from 391666ea1b28a76aeba74744148b15099254d918671Owen Lin // the "Camera" list. 392666ea1b28a76aeba74744148b15099254d918671Owen Lin if (i >= 3 && lists[i].getCount() == lists[i - 3].getCount()) { 393666ea1b28a76aeba74744148b15099254d918671Owen Lin continue; 394666ea1b28a76aeba74744148b15099254d918671Owen Lin } 395666ea1b28a76aeba74744148b15099254d918671Owen Lin 396666ea1b28a76aeba74744148b15099254d918671Owen Lin item = new Item(data.mType, 397666ea1b28a76aeba74744148b15099254d918671Owen Lin data.mBucketId, 398666ea1b28a76aeba74744148b15099254d918671Owen Lin getResources().getString(data.mStringId), 399666ea1b28a76aeba74744148b15099254d918671Owen Lin lists[i]); 400666ea1b28a76aeba74744148b15099254d918671Owen Lin 401666ea1b28a76aeba74744148b15099254d918671Owen Lin allItems.add(item); 402666ea1b28a76aeba74744148b15099254d918671Owen Lin 403666ea1b28a76aeba74744148b15099254d918671Owen Lin final Item finalItem = item; 404666ea1b28a76aeba74744148b15099254d918671Owen Lin mHandler.post(new Runnable() { 405666ea1b28a76aeba74744148b15099254d918671Owen Lin public void run() { 406666ea1b28a76aeba74744148b15099254d918671Owen Lin updateItem(finalItem); 407666ea1b28a76aeba74744148b15099254d918671Owen Lin } 408666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 409666ea1b28a76aeba74744148b15099254d918671Owen Lin } 410666ea1b28a76aeba74744148b15099254d918671Owen Lin } 411666ea1b28a76aeba74744148b15099254d918671Owen Lin 412666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the main thread. 413666ea1b28a76aeba74744148b15099254d918671Owen Lin private void updateItem(Item item) { 414666ea1b28a76aeba74744148b15099254d918671Owen Lin // Hide NoImageView if we are going to add the first item 415666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAdapter.getCount() == 0) { 416666ea1b28a76aeba74744148b15099254d918671Owen Lin hideNoImagesView(); 417666ea1b28a76aeba74744148b15099254d918671Owen Lin } 418666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter.addItem(item); 419666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter.updateDisplay(); 420666ea1b28a76aeba74744148b15099254d918671Owen Lin } 421666ea1b28a76aeba74744148b15099254d918671Owen Lin 422666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final String CAMERA_BUCKET = 423666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.CAMERA_IMAGE_BUCKET_ID; 424666ea1b28a76aeba74744148b15099254d918671Owen Lin 425666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the worker thread. 426666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkBucketIds(ArrayList<Item> allItems) { 427666ea1b28a76aeba74744148b15099254d918671Owen Lin final IImageList allImages; 428666ea1b28a76aeba74744148b15099254d918671Owen Lin if (!mScanning && !mUnmounted) { 429666ea1b28a76aeba74744148b15099254d918671Owen Lin allImages = ImageManager.makeImageList( 430666ea1b28a76aeba74744148b15099254d918671Owen Lin getContentResolver(), 431666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.DataLocation.ALL, 432666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS, 433666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.SORT_DESCENDING, 434666ea1b28a76aeba74744148b15099254d918671Owen Lin null); 435666ea1b28a76aeba74744148b15099254d918671Owen Lin } else { 436666ea1b28a76aeba74744148b15099254d918671Owen Lin allImages = ImageManager.makeEmptyImageList(); 437666ea1b28a76aeba74744148b15099254d918671Owen Lin } 438666ea1b28a76aeba74744148b15099254d918671Owen Lin 439666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) { 440666ea1b28a76aeba74744148b15099254d918671Owen Lin allImages.close(); 441666ea1b28a76aeba74744148b15099254d918671Owen Lin return; 442666ea1b28a76aeba74744148b15099254d918671Owen Lin } 443666ea1b28a76aeba74744148b15099254d918671Owen Lin 444666ea1b28a76aeba74744148b15099254d918671Owen Lin HashMap<String, String> hashMap = allImages.getBucketIds(); 445666ea1b28a76aeba74744148b15099254d918671Owen Lin allImages.close(); 446666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) return; 447666ea1b28a76aeba74744148b15099254d918671Owen Lin 448666ea1b28a76aeba74744148b15099254d918671Owen Lin for (Map.Entry<String, String> entry : hashMap.entrySet()) { 449666ea1b28a76aeba74744148b15099254d918671Owen Lin String key = entry.getKey(); 450666ea1b28a76aeba74744148b15099254d918671Owen Lin if (key == null) { 451666ea1b28a76aeba74744148b15099254d918671Owen Lin continue; 452666ea1b28a76aeba74744148b15099254d918671Owen Lin } 453666ea1b28a76aeba74744148b15099254d918671Owen Lin if (!key.equals(CAMERA_BUCKET)) { 454666ea1b28a76aeba74744148b15099254d918671Owen Lin IImageList list = createImageList( 455666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.INCLUDE_IMAGES 456666ea1b28a76aeba74744148b15099254d918671Owen Lin | ImageManager.INCLUDE_VIDEOS, key, 457666ea1b28a76aeba74744148b15099254d918671Owen Lin getContentResolver()); 458666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) return; 459666ea1b28a76aeba74744148b15099254d918671Owen Lin 460666ea1b28a76aeba74744148b15099254d918671Owen Lin Item item = new Item(Item.TYPE_NORMAL_FOLDERS, key, 461666ea1b28a76aeba74744148b15099254d918671Owen Lin entry.getValue(), list); 462666ea1b28a76aeba74744148b15099254d918671Owen Lin 463666ea1b28a76aeba74744148b15099254d918671Owen Lin allItems.add(item); 464666ea1b28a76aeba74744148b15099254d918671Owen Lin 465666ea1b28a76aeba74744148b15099254d918671Owen Lin final Item finalItem = item; 466666ea1b28a76aeba74744148b15099254d918671Owen Lin mHandler.post(new Runnable() { 467666ea1b28a76aeba74744148b15099254d918671Owen Lin public void run() { 468666ea1b28a76aeba74744148b15099254d918671Owen Lin updateItem(finalItem); 469666ea1b28a76aeba74744148b15099254d918671Owen Lin } 470666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 471666ea1b28a76aeba74744148b15099254d918671Owen Lin } 472666ea1b28a76aeba74744148b15099254d918671Owen Lin } 473666ea1b28a76aeba74744148b15099254d918671Owen Lin 474666ea1b28a76aeba74744148b15099254d918671Owen Lin mHandler.post(new Runnable() { 475666ea1b28a76aeba74744148b15099254d918671Owen Lin public void run() { 476666ea1b28a76aeba74744148b15099254d918671Owen Lin checkBucketIdsFinished(); 477666ea1b28a76aeba74744148b15099254d918671Owen Lin } 478666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 479666ea1b28a76aeba74744148b15099254d918671Owen Lin } 480666ea1b28a76aeba74744148b15099254d918671Owen Lin 481666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the main thread. 482666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkBucketIdsFinished() { 483666ea1b28a76aeba74744148b15099254d918671Owen Lin 484666ea1b28a76aeba74744148b15099254d918671Owen Lin // If we just have one folder, open it. 485666ea1b28a76aeba74744148b15099254d918671Owen Lin // If we have zero folder, show the "no images" icon. 486666ea1b28a76aeba74744148b15099254d918671Owen Lin if (!mScanning) { 487666ea1b28a76aeba74744148b15099254d918671Owen Lin int numItems = mAdapter.mItems.size(); 488666ea1b28a76aeba74744148b15099254d918671Owen Lin if (numItems == 0) { 489666ea1b28a76aeba74744148b15099254d918671Owen Lin showNoImagesView(); 490666ea1b28a76aeba74744148b15099254d918671Owen Lin } else if (numItems == 1) { 491666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter.mItems.get(0).launch(this); 492666ea1b28a76aeba74744148b15099254d918671Owen Lin finish(); 493666ea1b28a76aeba74744148b15099254d918671Owen Lin return; 494666ea1b28a76aeba74744148b15099254d918671Owen Lin } 495666ea1b28a76aeba74744148b15099254d918671Owen Lin } 496666ea1b28a76aeba74744148b15099254d918671Owen Lin } 497666ea1b28a76aeba74744148b15099254d918671Owen Lin 498666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final int THUMB_SIZE = 142; 499666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the worker thread. 500666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkThumbBitmap(ArrayList<Item> allItems) { 501666ea1b28a76aeba74744148b15099254d918671Owen Lin for (Item item : allItems) { 502666ea1b28a76aeba74744148b15099254d918671Owen Lin final Bitmap b = makeMiniThumbBitmap(THUMB_SIZE, THUMB_SIZE, 503666ea1b28a76aeba74744148b15099254d918671Owen Lin item.mImageList); 504666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) { 505666ea1b28a76aeba74744148b15099254d918671Owen Lin if (b != null) b.recycle(); 506666ea1b28a76aeba74744148b15099254d918671Owen Lin return; 507666ea1b28a76aeba74744148b15099254d918671Owen Lin } 508666ea1b28a76aeba74744148b15099254d918671Owen Lin 509666ea1b28a76aeba74744148b15099254d918671Owen Lin final Item finalItem = item; 510666ea1b28a76aeba74744148b15099254d918671Owen Lin mHandler.post(new Runnable() { 511666ea1b28a76aeba74744148b15099254d918671Owen Lin public void run() { 512666ea1b28a76aeba74744148b15099254d918671Owen Lin updateThumbBitmap(finalItem, b); 513666ea1b28a76aeba74744148b15099254d918671Owen Lin } 514666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 515666ea1b28a76aeba74744148b15099254d918671Owen Lin } 516666ea1b28a76aeba74744148b15099254d918671Owen Lin } 517666ea1b28a76aeba74744148b15099254d918671Owen Lin 518666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the main thread. 519666ea1b28a76aeba74744148b15099254d918671Owen Lin private void updateThumbBitmap(Item item, Bitmap b) { 520666ea1b28a76aeba74744148b15099254d918671Owen Lin item.setThumbBitmap(b); 521666ea1b28a76aeba74744148b15099254d918671Owen Lin mAdapter.updateDisplay(); 522666ea1b28a76aeba74744148b15099254d918671Owen Lin } 523666ea1b28a76aeba74744148b15099254d918671Owen Lin 524666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final long LOW_STORAGE_THRESHOLD = 1024 * 1024 * 2; 525666ea1b28a76aeba74744148b15099254d918671Owen Lin 526666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the worker thread. 527666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkLowStorage() { 528666ea1b28a76aeba74744148b15099254d918671Owen Lin // Check available space only if we are writable 529666ea1b28a76aeba74744148b15099254d918671Owen Lin if (ImageManager.hasStorage()) { 530666ea1b28a76aeba74744148b15099254d918671Owen Lin String storageDirectory = Environment 531666ea1b28a76aeba74744148b15099254d918671Owen Lin .getExternalStorageDirectory().toString(); 532666ea1b28a76aeba74744148b15099254d918671Owen Lin StatFs stat = new StatFs(storageDirectory); 533666ea1b28a76aeba74744148b15099254d918671Owen Lin long remaining = (long) stat.getAvailableBlocks() 534666ea1b28a76aeba74744148b15099254d918671Owen Lin * (long) stat.getBlockSize(); 535666ea1b28a76aeba74744148b15099254d918671Owen Lin if (remaining < LOW_STORAGE_THRESHOLD) { 536666ea1b28a76aeba74744148b15099254d918671Owen Lin mHandler.post(new Runnable() { 537666ea1b28a76aeba74744148b15099254d918671Owen Lin public void run() { 538666ea1b28a76aeba74744148b15099254d918671Owen Lin checkLowStorageFinished(); 539666ea1b28a76aeba74744148b15099254d918671Owen Lin } 540666ea1b28a76aeba74744148b15099254d918671Owen Lin }); 541666ea1b28a76aeba74744148b15099254d918671Owen Lin } 542666ea1b28a76aeba74744148b15099254d918671Owen Lin } 543666ea1b28a76aeba74744148b15099254d918671Owen Lin } 544666ea1b28a76aeba74744148b15099254d918671Owen Lin 545666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in the main thread. 546666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is called only if the storage is low. 547666ea1b28a76aeba74744148b15099254d918671Owen Lin private void checkLowStorageFinished() { 548666ea1b28a76aeba74744148b15099254d918671Owen Lin Toast.makeText(GalleryPicker.this, R.string.not_enough_space, 5000) 549666ea1b28a76aeba74744148b15099254d918671Owen Lin .show(); 550666ea1b28a76aeba74744148b15099254d918671Owen Lin } 551666ea1b28a76aeba74744148b15099254d918671Owen Lin 552666ea1b28a76aeba74744148b15099254d918671Owen Lin // IMAGE_LIST_DATA stores the parameters for the four image lists 553666ea1b28a76aeba74744148b15099254d918671Owen Lin // we are interested in. The order of the IMAGE_LIST_DATA array is 554666ea1b28a76aeba74744148b15099254d918671Owen Lin // significant (See the implementation of GalleryPickerAdapter.init). 555666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final class ImageListData { 556666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageListData(int type, int include, String bucketId, int stringId) { 557666ea1b28a76aeba74744148b15099254d918671Owen Lin mType = type; 558666ea1b28a76aeba74744148b15099254d918671Owen Lin mInclude = include; 559666ea1b28a76aeba74744148b15099254d918671Owen Lin mBucketId = bucketId; 560666ea1b28a76aeba74744148b15099254d918671Owen Lin mStringId = stringId; 561666ea1b28a76aeba74744148b15099254d918671Owen Lin } 562666ea1b28a76aeba74744148b15099254d918671Owen Lin int mType; 563666ea1b28a76aeba74744148b15099254d918671Owen Lin int mInclude; 564666ea1b28a76aeba74744148b15099254d918671Owen Lin String mBucketId; 565666ea1b28a76aeba74744148b15099254d918671Owen Lin int mStringId; 566666ea1b28a76aeba74744148b15099254d918671Owen Lin } 567666ea1b28a76aeba74744148b15099254d918671Owen Lin 568666ea1b28a76aeba74744148b15099254d918671Owen Lin private static final ImageListData[] IMAGE_LIST_DATA = { 569666ea1b28a76aeba74744148b15099254d918671Owen Lin // Camera Images 570666ea1b28a76aeba74744148b15099254d918671Owen Lin new ImageListData(Item.TYPE_CAMERA_IMAGES, 571666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.INCLUDE_IMAGES, 572666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.CAMERA_IMAGE_BUCKET_ID, 573666ea1b28a76aeba74744148b15099254d918671Owen Lin R.string.gallery_camera_bucket_name), 574666ea1b28a76aeba74744148b15099254d918671Owen Lin // Camera Videos 575666ea1b28a76aeba74744148b15099254d918671Owen Lin new ImageListData(Item.TYPE_CAMERA_VIDEOS, 576666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.INCLUDE_VIDEOS, 577666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.CAMERA_IMAGE_BUCKET_ID, 578666ea1b28a76aeba74744148b15099254d918671Owen Lin R.string.gallery_camera_videos_bucket_name), 579666ea1b28a76aeba74744148b15099254d918671Owen Lin 580666ea1b28a76aeba74744148b15099254d918671Owen Lin // Camera Medias 581666ea1b28a76aeba74744148b15099254d918671Owen Lin new ImageListData(Item.TYPE_CAMERA_MEDIAS, 582666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.INCLUDE_VIDEOS | ImageManager.INCLUDE_IMAGES, 583666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.CAMERA_IMAGE_BUCKET_ID, 584666ea1b28a76aeba74744148b15099254d918671Owen Lin R.string.gallery_camera_media_bucket_name), 585666ea1b28a76aeba74744148b15099254d918671Owen Lin 586666ea1b28a76aeba74744148b15099254d918671Owen Lin // All Images 587666ea1b28a76aeba74744148b15099254d918671Owen Lin new ImageListData(Item.TYPE_ALL_IMAGES, 588666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.INCLUDE_IMAGES, 589666ea1b28a76aeba74744148b15099254d918671Owen Lin null, 590666ea1b28a76aeba74744148b15099254d918671Owen Lin R.string.all_images), 591666ea1b28a76aeba74744148b15099254d918671Owen Lin 592666ea1b28a76aeba74744148b15099254d918671Owen Lin // All Videos 593666ea1b28a76aeba74744148b15099254d918671Owen Lin new ImageListData(Item.TYPE_ALL_VIDEOS, 594666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.INCLUDE_VIDEOS, 595666ea1b28a76aeba74744148b15099254d918671Owen Lin null, 596666ea1b28a76aeba74744148b15099254d918671Owen Lin R.string.all_videos), 597666ea1b28a76aeba74744148b15099254d918671Owen Lin }; 598666ea1b28a76aeba74744148b15099254d918671Owen Lin 599666ea1b28a76aeba74744148b15099254d918671Owen Lin 600666ea1b28a76aeba74744148b15099254d918671Owen Lin // These drawables are loaded on-demand. 601666ea1b28a76aeba74744148b15099254d918671Owen Lin Drawable mFrameGalleryMask; 602666ea1b28a76aeba74744148b15099254d918671Owen Lin Drawable mCellOutline; 603666ea1b28a76aeba74744148b15099254d918671Owen Lin Drawable mVideoOverlay; 604666ea1b28a76aeba74744148b15099254d918671Owen Lin 605666ea1b28a76aeba74744148b15099254d918671Owen Lin private void loadDrawableIfNeeded() { 606666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mFrameGalleryMask != null) return; // already loaded 607666ea1b28a76aeba74744148b15099254d918671Owen Lin Resources r = getResources(); 608666ea1b28a76aeba74744148b15099254d918671Owen Lin mFrameGalleryMask = r.getDrawable( 609666ea1b28a76aeba74744148b15099254d918671Owen Lin R.drawable.frame_gallery_preview_album_mask); 610666ea1b28a76aeba74744148b15099254d918671Owen Lin mCellOutline = r.getDrawable(android.R.drawable.gallery_thumb); 611666ea1b28a76aeba74744148b15099254d918671Owen Lin mVideoOverlay = r.getDrawable(R.drawable.ic_gallery_video_overlay); 612666ea1b28a76aeba74744148b15099254d918671Owen Lin } 613666ea1b28a76aeba74744148b15099254d918671Owen Lin 614666ea1b28a76aeba74744148b15099254d918671Owen Lin private void unloadDrawable() { 615666ea1b28a76aeba74744148b15099254d918671Owen Lin mFrameGalleryMask = null; 616666ea1b28a76aeba74744148b15099254d918671Owen Lin mCellOutline = null; 617666ea1b28a76aeba74744148b15099254d918671Owen Lin mVideoOverlay = null; 618666ea1b28a76aeba74744148b15099254d918671Owen Lin } 619666ea1b28a76aeba74744148b15099254d918671Owen Lin 620666ea1b28a76aeba74744148b15099254d918671Owen Lin private static void placeImage(Bitmap image, Canvas c, Paint paint, 621666ea1b28a76aeba74744148b15099254d918671Owen Lin int imageWidth, int widthPadding, int imageHeight, 622666ea1b28a76aeba74744148b15099254d918671Owen Lin int heightPadding, int offsetX, int offsetY, 623666ea1b28a76aeba74744148b15099254d918671Owen Lin int pos) { 624666ea1b28a76aeba74744148b15099254d918671Owen Lin int row = pos / 2; 625666ea1b28a76aeba74744148b15099254d918671Owen Lin int col = pos - (row * 2); 626666ea1b28a76aeba74744148b15099254d918671Owen Lin 627666ea1b28a76aeba74744148b15099254d918671Owen Lin int xPos = (col * (imageWidth + widthPadding)) - offsetX; 628666ea1b28a76aeba74744148b15099254d918671Owen Lin int yPos = (row * (imageHeight + heightPadding)) - offsetY; 629666ea1b28a76aeba74744148b15099254d918671Owen Lin 630666ea1b28a76aeba74744148b15099254d918671Owen Lin c.drawBitmap(image, xPos, yPos, paint); 631666ea1b28a76aeba74744148b15099254d918671Owen Lin } 632666ea1b28a76aeba74744148b15099254d918671Owen Lin 633666ea1b28a76aeba74744148b15099254d918671Owen Lin // This is run in worker thread. 634666ea1b28a76aeba74744148b15099254d918671Owen Lin private Bitmap makeMiniThumbBitmap(int width, int height, 635666ea1b28a76aeba74744148b15099254d918671Owen Lin IImageList images) { 636666ea1b28a76aeba74744148b15099254d918671Owen Lin int count = images.getCount(); 637666ea1b28a76aeba74744148b15099254d918671Owen Lin // We draw three different version of the folder image depending on the 638666ea1b28a76aeba74744148b15099254d918671Owen Lin // number of images in the folder. 639666ea1b28a76aeba74744148b15099254d918671Owen Lin // For a single image, that image draws over the whole folder. 640666ea1b28a76aeba74744148b15099254d918671Owen Lin // For two or three images, we draw the two most recent photos. 641666ea1b28a76aeba74744148b15099254d918671Owen Lin // For four or more images, we draw four photos. 642666ea1b28a76aeba74744148b15099254d918671Owen Lin final int padding = 4; 643666ea1b28a76aeba74744148b15099254d918671Owen Lin int imageWidth = width; 644666ea1b28a76aeba74744148b15099254d918671Owen Lin int imageHeight = height; 645666ea1b28a76aeba74744148b15099254d918671Owen Lin int offsetWidth = 0; 646666ea1b28a76aeba74744148b15099254d918671Owen Lin int offsetHeight = 0; 647666ea1b28a76aeba74744148b15099254d918671Owen Lin 648666ea1b28a76aeba74744148b15099254d918671Owen Lin imageWidth = (imageWidth - padding) / 2; // 2 here because we show two 649666ea1b28a76aeba74744148b15099254d918671Owen Lin // images 650666ea1b28a76aeba74744148b15099254d918671Owen Lin imageHeight = (imageHeight - padding) / 2; // per row and column 651666ea1b28a76aeba74744148b15099254d918671Owen Lin 652666ea1b28a76aeba74744148b15099254d918671Owen Lin final Paint p = new Paint(); 653666ea1b28a76aeba74744148b15099254d918671Owen Lin final Bitmap b = Bitmap.createBitmap(width, height, 654666ea1b28a76aeba74744148b15099254d918671Owen Lin Bitmap.Config.ARGB_8888); 655666ea1b28a76aeba74744148b15099254d918671Owen Lin final Canvas c = new Canvas(b); 656666ea1b28a76aeba74744148b15099254d918671Owen Lin final Matrix m = new Matrix(); 657666ea1b28a76aeba74744148b15099254d918671Owen Lin 658666ea1b28a76aeba74744148b15099254d918671Owen Lin // draw the whole canvas as transparent 659666ea1b28a76aeba74744148b15099254d918671Owen Lin p.setColor(0x00000000); 660666ea1b28a76aeba74744148b15099254d918671Owen Lin c.drawPaint(p); 661666ea1b28a76aeba74744148b15099254d918671Owen Lin 662666ea1b28a76aeba74744148b15099254d918671Owen Lin // load the drawables 663666ea1b28a76aeba74744148b15099254d918671Owen Lin loadDrawableIfNeeded(); 664666ea1b28a76aeba74744148b15099254d918671Owen Lin 665666ea1b28a76aeba74744148b15099254d918671Owen Lin // draw the mask normally 666666ea1b28a76aeba74744148b15099254d918671Owen Lin p.setColor(0xFFFFFFFF); 667666ea1b28a76aeba74744148b15099254d918671Owen Lin mFrameGalleryMask.setBounds(0, 0, width, height); 668666ea1b28a76aeba74744148b15099254d918671Owen Lin mFrameGalleryMask.draw(c); 669666ea1b28a76aeba74744148b15099254d918671Owen Lin 670666ea1b28a76aeba74744148b15099254d918671Owen Lin Paint pdpaint = new Paint(); 671666ea1b28a76aeba74744148b15099254d918671Owen Lin pdpaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 672666ea1b28a76aeba74744148b15099254d918671Owen Lin 673666ea1b28a76aeba74744148b15099254d918671Owen Lin pdpaint.setStyle(Paint.Style.FILL); 674666ea1b28a76aeba74744148b15099254d918671Owen Lin c.drawRect(0, 0, width, height, pdpaint); 675666ea1b28a76aeba74744148b15099254d918671Owen Lin 676666ea1b28a76aeba74744148b15099254d918671Owen Lin for (int i = 0; i < 4; i++) { 677666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mAbort) { 678666ea1b28a76aeba74744148b15099254d918671Owen Lin return null; 679666ea1b28a76aeba74744148b15099254d918671Owen Lin } 680666ea1b28a76aeba74744148b15099254d918671Owen Lin 681666ea1b28a76aeba74744148b15099254d918671Owen Lin Bitmap temp = null; 682666ea1b28a76aeba74744148b15099254d918671Owen Lin IImage image = i < count ? images.getImageAt(i) : null; 683666ea1b28a76aeba74744148b15099254d918671Owen Lin 684666ea1b28a76aeba74744148b15099254d918671Owen Lin if (image != null) { 685666ea1b28a76aeba74744148b15099254d918671Owen Lin temp = image.miniThumbBitmap(); 686666ea1b28a76aeba74744148b15099254d918671Owen Lin } 687666ea1b28a76aeba74744148b15099254d918671Owen Lin 688666ea1b28a76aeba74744148b15099254d918671Owen Lin if (temp != null) { 689666ea1b28a76aeba74744148b15099254d918671Owen Lin if (ImageManager.isVideo(image)) { 690666ea1b28a76aeba74744148b15099254d918671Owen Lin Bitmap newMap = temp.copy(temp.getConfig(), true); 691666ea1b28a76aeba74744148b15099254d918671Owen Lin Canvas overlayCanvas = new Canvas(newMap); 692666ea1b28a76aeba74744148b15099254d918671Owen Lin int overlayWidth = mVideoOverlay.getIntrinsicWidth(); 693666ea1b28a76aeba74744148b15099254d918671Owen Lin int overlayHeight = mVideoOverlay.getIntrinsicHeight(); 694666ea1b28a76aeba74744148b15099254d918671Owen Lin int left = (newMap.getWidth() - overlayWidth) / 2; 695666ea1b28a76aeba74744148b15099254d918671Owen Lin int top = (newMap.getHeight() - overlayHeight) / 2; 696666ea1b28a76aeba74744148b15099254d918671Owen Lin Rect newBounds = new Rect(left, top, left + overlayWidth, 697666ea1b28a76aeba74744148b15099254d918671Owen Lin top + overlayHeight); 698666ea1b28a76aeba74744148b15099254d918671Owen Lin mVideoOverlay.setBounds(newBounds); 699666ea1b28a76aeba74744148b15099254d918671Owen Lin mVideoOverlay.draw(overlayCanvas); 700666ea1b28a76aeba74744148b15099254d918671Owen Lin temp.recycle(); 701666ea1b28a76aeba74744148b15099254d918671Owen Lin temp = newMap; 702666ea1b28a76aeba74744148b15099254d918671Owen Lin } 703666ea1b28a76aeba74744148b15099254d918671Owen Lin 704666ea1b28a76aeba74744148b15099254d918671Owen Lin temp = Util.transform(m, temp, imageWidth, 705666ea1b28a76aeba74744148b15099254d918671Owen Lin imageHeight, true, Util.RECYCLE_INPUT); 706666ea1b28a76aeba74744148b15099254d918671Owen Lin } 707666ea1b28a76aeba74744148b15099254d918671Owen Lin 708666ea1b28a76aeba74744148b15099254d918671Owen Lin Bitmap thumb = Bitmap.createBitmap(imageWidth, imageHeight, 709666ea1b28a76aeba74744148b15099254d918671Owen Lin Bitmap.Config.ARGB_8888); 710666ea1b28a76aeba74744148b15099254d918671Owen Lin Canvas tempCanvas = new Canvas(thumb); 711666ea1b28a76aeba74744148b15099254d918671Owen Lin if (temp != null) { 712666ea1b28a76aeba74744148b15099254d918671Owen Lin tempCanvas.drawBitmap(temp, new Matrix(), new Paint()); 713666ea1b28a76aeba74744148b15099254d918671Owen Lin } 714666ea1b28a76aeba74744148b15099254d918671Owen Lin mCellOutline.setBounds(0, 0, imageWidth, imageHeight); 715666ea1b28a76aeba74744148b15099254d918671Owen Lin mCellOutline.draw(tempCanvas); 716666ea1b28a76aeba74744148b15099254d918671Owen Lin 717666ea1b28a76aeba74744148b15099254d918671Owen Lin placeImage(thumb, c, pdpaint, imageWidth, padding, imageHeight, 718666ea1b28a76aeba74744148b15099254d918671Owen Lin padding, offsetWidth, offsetHeight, i); 719666ea1b28a76aeba74744148b15099254d918671Owen Lin 720666ea1b28a76aeba74744148b15099254d918671Owen Lin thumb.recycle(); 721666ea1b28a76aeba74744148b15099254d918671Owen Lin 722666ea1b28a76aeba74744148b15099254d918671Owen Lin if (temp != null) { 723666ea1b28a76aeba74744148b15099254d918671Owen Lin temp.recycle(); 724666ea1b28a76aeba74744148b15099254d918671Owen Lin } 725666ea1b28a76aeba74744148b15099254d918671Owen Lin } 726666ea1b28a76aeba74744148b15099254d918671Owen Lin 727666ea1b28a76aeba74744148b15099254d918671Owen Lin return b; 728666ea1b28a76aeba74744148b15099254d918671Owen Lin } 729666ea1b28a76aeba74744148b15099254d918671Owen Lin 730666ea1b28a76aeba74744148b15099254d918671Owen Lin @Override 731666ea1b28a76aeba74744148b15099254d918671Owen Lin public boolean onCreateOptionsMenu(Menu menu) { 732666ea1b28a76aeba74744148b15099254d918671Owen Lin super.onCreateOptionsMenu(menu); 733666ea1b28a76aeba74744148b15099254d918671Owen Lin 734666ea1b28a76aeba74744148b15099254d918671Owen Lin MenuHelper.addCaptureMenuItems(menu, this); 735666ea1b28a76aeba74744148b15099254d918671Owen Lin 736666ea1b28a76aeba74744148b15099254d918671Owen Lin menu.add(Menu.NONE, Menu.NONE, MenuHelper.POSITION_GALLERY_SETTING, 737666ea1b28a76aeba74744148b15099254d918671Owen Lin R.string.camerasettings) 738666ea1b28a76aeba74744148b15099254d918671Owen Lin .setOnMenuItemClickListener(new OnMenuItemClickListener() { 739666ea1b28a76aeba74744148b15099254d918671Owen Lin public boolean onMenuItemClick(MenuItem item) { 740666ea1b28a76aeba74744148b15099254d918671Owen Lin Intent preferences = new Intent(); 741666ea1b28a76aeba74744148b15099254d918671Owen Lin preferences.setClass(GalleryPicker.this, 742666ea1b28a76aeba74744148b15099254d918671Owen Lin GallerySettings.class); 743666ea1b28a76aeba74744148b15099254d918671Owen Lin startActivity(preferences); 744666ea1b28a76aeba74744148b15099254d918671Owen Lin return true; 745666ea1b28a76aeba74744148b15099254d918671Owen Lin } 746666ea1b28a76aeba74744148b15099254d918671Owen Lin }) 747666ea1b28a76aeba74744148b15099254d918671Owen Lin .setAlphabeticShortcut('p') 748666ea1b28a76aeba74744148b15099254d918671Owen Lin .setIcon(android.R.drawable.ic_menu_preferences); 749666ea1b28a76aeba74744148b15099254d918671Owen Lin 750666ea1b28a76aeba74744148b15099254d918671Owen Lin return true; 751666ea1b28a76aeba74744148b15099254d918671Owen Lin } 752666ea1b28a76aeba74744148b15099254d918671Owen Lin 753666ea1b28a76aeba74744148b15099254d918671Owen Lin // image lists created by createImageList() are collected in mAllLists. 754666ea1b28a76aeba74744148b15099254d918671Owen Lin // They will be closed in clearImageList, so they don't hold open files 755666ea1b28a76aeba74744148b15099254d918671Owen Lin // on SD card. We will be killed if we don't close files when the SD card 756666ea1b28a76aeba74744148b15099254d918671Owen Lin // is unmounted. 757666ea1b28a76aeba74744148b15099254d918671Owen Lin ArrayList<IImageList> mAllLists = new ArrayList<IImageList>(); 758666ea1b28a76aeba74744148b15099254d918671Owen Lin 759666ea1b28a76aeba74744148b15099254d918671Owen Lin private IImageList createImageList(int mediaTypes, String bucketId, 760666ea1b28a76aeba74744148b15099254d918671Owen Lin ContentResolver cr) { 761666ea1b28a76aeba74744148b15099254d918671Owen Lin IImageList list = ImageManager.makeImageList( 762666ea1b28a76aeba74744148b15099254d918671Owen Lin cr, 763666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.DataLocation.ALL, 764666ea1b28a76aeba74744148b15099254d918671Owen Lin mediaTypes, 765666ea1b28a76aeba74744148b15099254d918671Owen Lin ImageManager.SORT_DESCENDING, 766666ea1b28a76aeba74744148b15099254d918671Owen Lin bucketId); 767666ea1b28a76aeba74744148b15099254d918671Owen Lin mAllLists.add(list); 768666ea1b28a76aeba74744148b15099254d918671Owen Lin return list; 769666ea1b28a76aeba74744148b15099254d918671Owen Lin } 770666ea1b28a76aeba74744148b15099254d918671Owen Lin 771666ea1b28a76aeba74744148b15099254d918671Owen Lin private void clearImageLists() { 772666ea1b28a76aeba74744148b15099254d918671Owen Lin for (IImageList list : mAllLists) { 773666ea1b28a76aeba74744148b15099254d918671Owen Lin list.close(); 774666ea1b28a76aeba74744148b15099254d918671Owen Lin } 775666ea1b28a76aeba74744148b15099254d918671Owen Lin mAllLists.clear(); 776666ea1b28a76aeba74744148b15099254d918671Owen Lin } 777666ea1b28a76aeba74744148b15099254d918671Owen Lin} 778666ea1b28a76aeba74744148b15099254d918671Owen Lin 779666ea1b28a76aeba74744148b15099254d918671Owen Lin// Item is the underlying data for GalleryPickerAdapter. 780666ea1b28a76aeba74744148b15099254d918671Owen Lin// It is passed from the activity to the adapter. 781666ea1b28a76aeba74744148b15099254d918671Owen Linclass Item { 782666ea1b28a76aeba74744148b15099254d918671Owen Lin public static final int TYPE_NONE = -1; 783666ea1b28a76aeba74744148b15099254d918671Owen Lin public static final int TYPE_ALL_IMAGES = 0; 784666ea1b28a76aeba74744148b15099254d918671Owen Lin public static final int TYPE_ALL_VIDEOS = 1; 785666ea1b28a76aeba74744148b15099254d918671Owen Lin public static final int TYPE_CAMERA_IMAGES = 2; 786666ea1b28a76aeba74744148b15099254d918671Owen Lin public static final int TYPE_CAMERA_VIDEOS = 3; 787666ea1b28a76aeba74744148b15099254d918671Owen Lin public static final int TYPE_CAMERA_MEDIAS = 4; 788666ea1b28a76aeba74744148b15099254d918671Owen Lin public static final int TYPE_NORMAL_FOLDERS = 5; 789666ea1b28a76aeba74744148b15099254d918671Owen Lin 790666ea1b28a76aeba74744148b15099254d918671Owen Lin public final int mType; 791666ea1b28a76aeba74744148b15099254d918671Owen Lin public final String mBucketId; 792666ea1b28a76aeba74744148b15099254d918671Owen Lin public final String mName; 793666ea1b28a76aeba74744148b15099254d918671Owen Lin public final IImageList mImageList; 794666ea1b28a76aeba74744148b15099254d918671Owen Lin public final int mCount; 795666ea1b28a76aeba74744148b15099254d918671Owen Lin public final Uri mFirstImageUri; // could be null if the list is empty 796666ea1b28a76aeba74744148b15099254d918671Owen Lin 797666ea1b28a76aeba74744148b15099254d918671Owen Lin // The thumbnail bitmap is set by setThumbBitmap() later because we want 798666ea1b28a76aeba74744148b15099254d918671Owen Lin // to let the user sees the folder icon as soon as possible (and possibly 799666ea1b28a76aeba74744148b15099254d918671Owen Lin // select them), then present more detailed information when we have it. 800666ea1b28a76aeba74744148b15099254d918671Owen Lin public Bitmap mThumbBitmap; // the thumbnail bitmap for the image list 801666ea1b28a76aeba74744148b15099254d918671Owen Lin 802666ea1b28a76aeba74744148b15099254d918671Owen Lin public Item(int type, String bucketId, String name, IImageList list) { 803666ea1b28a76aeba74744148b15099254d918671Owen Lin mType = type; 804666ea1b28a76aeba74744148b15099254d918671Owen Lin mBucketId = bucketId; 805666ea1b28a76aeba74744148b15099254d918671Owen Lin mName = name; 806666ea1b28a76aeba74744148b15099254d918671Owen Lin mImageList = list; 807666ea1b28a76aeba74744148b15099254d918671Owen Lin mCount = list.getCount(); 808666ea1b28a76aeba74744148b15099254d918671Owen Lin if (mCount > 0) { 809666ea1b28a76aeba74744148b15099254d918671Owen Lin mFirstImageUri = list.getImageAt(0).fullSizeImageUri(); 810666ea1b28a76aeba74744148b15099254d918671Owen Lin } else { 811666ea1b28a76aeba74744148b15099254d918671Owen Lin mFirstImageUri = null; 812666ea1b28a76aeba74744148b15099254d918671Owen Lin } 813666ea1b28a76aeba74744148b15099254d918671Owen Lin } 814666ea1b28a76aeba74744148b15099254d918671Owen Lin 815666ea1b28a76aeba74744148b15099254d918671Owen Lin public void setThumbBitmap(Bitmap thumbBitmap) { 816666ea1b28a76aeba74744148b15099254d918671Owen Lin mThumbBitmap = thumbBitmap; 817666ea1b28a76aeba74744148b15099254d918671Owen Lin } 818666ea1b28a76aeba74744148b15099254d918671Owen Lin 819666ea1b28a76aeba74744148b15099254d918671Owen Lin public boolean needsBucketId() { 820666ea1b28a76aeba74744148b15099254d918671Owen Lin return mType >= TYPE_CAMERA_IMAGES; 821666ea1b28a76aeba74744148b15099254d918671Owen Lin } 822666ea1b28a76aeba74744148b15099254d918671Owen Lin 823666ea1b28a76aeba74744148b15099254d918671Owen Lin public void launch(Activity activity) { 824666ea1b28a76aeba74744148b15099254d918671Owen Lin Uri uri = Images.Media.INTERNAL_CONTENT_URI; 825666ea1b28a76aeba74744148b15099254d918671Owen Lin if (needsBucketId()) { 826666ea1b28a76aeba74744148b15099254d918671Owen Lin uri = uri.buildUpon() 827666ea1b28a76aeba74744148b15099254d918671Owen Lin .appendQueryParameter("bucketId", mBucketId).build(); 828666ea1b28a76aeba74744148b15099254d918671Owen Lin } 829666ea1b28a76aeba74744148b15099254d918671Owen Lin Intent intent = new Intent(Intent.ACTION_VIEW, uri); 830666ea1b28a76aeba74744148b15099254d918671Owen Lin intent.putExtra("windowTitle", mName); 831666ea1b28a76aeba74744148b15099254d918671Owen Lin intent.putExtra("mediaTypes", getIncludeMediaTypes()); 832666ea1b28a76aeba74744148b15099254d918671Owen Lin activity.startActivity(intent); 833666ea1b28a76aeba74744148b15099254d918671Owen Lin } 834666ea1b28a76aeba74744148b15099254d918671Owen Lin 835666ea1b28a76aeba74744148b15099254d918671Owen Lin public int getIncludeMediaTypes() { 836666ea1b28a76aeba74744148b15099254d918671Owen Lin return convertItemTypeToIncludedMediaType(mType); 837666ea1b28a76aeba74744148b15099254d918671Owen Lin } 838666ea1b28a76aeba74744148b15099254d918671Owen Lin 839666ea1b28a76aeba74744148b15099254d918671Owen Lin public static int convertItemTypeToIncludedMediaType(int itemType) { 840666ea1b28a76aeba74744148b15099254d918671Owen Lin switch (itemType) { 841666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_ALL_IMAGES: 842666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_CAMERA_IMAGES: 843666ea1b28a76aeba74744148b15099254d918671Owen Lin return ImageManager.INCLUDE_IMAGES; 844666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_ALL_VIDEOS: 845666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_CAMERA_VIDEOS: 846666ea1b28a76aeba74744148b15099254d918671Owen Lin return ImageManager.INCLUDE_VIDEOS; 847666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_NORMAL_FOLDERS: 848666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_CAMERA_MEDIAS: 849666ea1b28a76aeba74744148b15099254d918671Owen Lin default: 850666ea1b28a76aeba74744148b15099254d918671Owen Lin return ImageManager.INCLUDE_IMAGES 851666ea1b28a76aeba74744148b15099254d918671Owen Lin | ImageManager.INCLUDE_VIDEOS; 852666ea1b28a76aeba74744148b15099254d918671Owen Lin } 853666ea1b28a76aeba74744148b15099254d918671Owen Lin } 854666ea1b28a76aeba74744148b15099254d918671Owen Lin 855666ea1b28a76aeba74744148b15099254d918671Owen Lin public int getOverlay() { 856666ea1b28a76aeba74744148b15099254d918671Owen Lin switch (mType) { 857666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_ALL_IMAGES: 858666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_CAMERA_IMAGES: 859666ea1b28a76aeba74744148b15099254d918671Owen Lin return R.drawable.frame_overlay_gallery_camera; 860666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_ALL_VIDEOS: 861666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_CAMERA_VIDEOS: 862666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_CAMERA_MEDIAS: 863666ea1b28a76aeba74744148b15099254d918671Owen Lin return R.drawable.frame_overlay_gallery_video; 864666ea1b28a76aeba74744148b15099254d918671Owen Lin case TYPE_NORMAL_FOLDERS: 865666ea1b28a76aeba74744148b15099254d918671Owen Lin default: 866666ea1b28a76aeba74744148b15099254d918671Owen Lin return R.drawable.frame_overlay_gallery_folder; 867666ea1b28a76aeba74744148b15099254d918671Owen Lin } 868666ea1b28a76aeba74744148b15099254d918671Owen Lin } 869666ea1b28a76aeba74744148b15099254d918671Owen Lin} 870666ea1b28a76aeba74744148b15099254d918671Owen Lin 871666ea1b28a76aeba74744148b15099254d918671Owen Linclass GalleryPickerAdapter extends BaseAdapter { 872666ea1b28a76aeba74744148b15099254d918671Owen Lin ArrayList<Item> mItems = new ArrayList<Item>(); 873666ea1b28a76aeba74744148b15099254d918671Owen Lin LayoutInflater mInflater; 874666ea1b28a76aeba74744148b15099254d918671Owen Lin 875666ea1b28a76aeba74744148b15099254d918671Owen Lin GalleryPickerAdapter(LayoutInflater inflater) { 876666ea1b28a76aeba74744148b15099254d918671Owen Lin mInflater = inflater; 877666ea1b28a76aeba74744148b15099254d918671Owen Lin } 878666ea1b28a76aeba74744148b15099254d918671Owen Lin 879666ea1b28a76aeba74744148b15099254d918671Owen Lin public void addItem(Item item) { 880666ea1b28a76aeba74744148b15099254d918671Owen Lin mItems.add(item); 881666ea1b28a76aeba74744148b15099254d918671Owen Lin } 882666ea1b28a76aeba74744148b15099254d918671Owen Lin 883666ea1b28a76aeba74744148b15099254d918671Owen Lin public void updateDisplay() { 884666ea1b28a76aeba74744148b15099254d918671Owen Lin notifyDataSetChanged(); 885666ea1b28a76aeba74744148b15099254d918671Owen Lin } 886666ea1b28a76aeba74744148b15099254d918671Owen Lin 887666ea1b28a76aeba74744148b15099254d918671Owen Lin public void clear() { 888666ea1b28a76aeba74744148b15099254d918671Owen Lin mItems.clear(); 889666ea1b28a76aeba74744148b15099254d918671Owen Lin } 890666ea1b28a76aeba74744148b15099254d918671Owen Lin 891666ea1b28a76aeba74744148b15099254d918671Owen Lin public int getCount() { 892666ea1b28a76aeba74744148b15099254d918671Owen Lin return mItems.size(); 893666ea1b28a76aeba74744148b15099254d918671Owen Lin } 894666ea1b28a76aeba74744148b15099254d918671Owen Lin 895666ea1b28a76aeba74744148b15099254d918671Owen Lin public Object getItem(int position) { 896666ea1b28a76aeba74744148b15099254d918671Owen Lin return null; 897666ea1b28a76aeba74744148b15099254d918671Owen Lin } 898666ea1b28a76aeba74744148b15099254d918671Owen Lin 899666ea1b28a76aeba74744148b15099254d918671Owen Lin public long getItemId(int position) { 900666ea1b28a76aeba74744148b15099254d918671Owen Lin return position; 901666ea1b28a76aeba74744148b15099254d918671Owen Lin } 902666ea1b28a76aeba74744148b15099254d918671Owen Lin 903666ea1b28a76aeba74744148b15099254d918671Owen Lin public String baseTitleForPosition(int position) { 904666ea1b28a76aeba74744148b15099254d918671Owen Lin return mItems.get(position).mName; 905666ea1b28a76aeba74744148b15099254d918671Owen Lin } 906666ea1b28a76aeba74744148b15099254d918671Owen Lin 907666ea1b28a76aeba74744148b15099254d918671Owen Lin public int getIncludeMediaTypes(int position) { 908666ea1b28a76aeba74744148b15099254d918671Owen Lin return mItems.get(position).getIncludeMediaTypes(); 909666ea1b28a76aeba74744148b15099254d918671Owen Lin } 910666ea1b28a76aeba74744148b15099254d918671Owen Lin 911666ea1b28a76aeba74744148b15099254d918671Owen Lin public View getView(final int position, View convertView, 912666ea1b28a76aeba74744148b15099254d918671Owen Lin ViewGroup parent) { 913666ea1b28a76aeba74744148b15099254d918671Owen Lin View v; 914666ea1b28a76aeba74744148b15099254d918671Owen Lin 915666ea1b28a76aeba74744148b15099254d918671Owen Lin if (convertView == null) { 916666ea1b28a76aeba74744148b15099254d918671Owen Lin v = mInflater.inflate(R.layout.gallery_picker_item, null); 917666ea1b28a76aeba74744148b15099254d918671Owen Lin } else { 918666ea1b28a76aeba74744148b15099254d918671Owen Lin v = convertView; 919666ea1b28a76aeba74744148b15099254d918671Owen Lin } 920666ea1b28a76aeba74744148b15099254d918671Owen Lin 921666ea1b28a76aeba74744148b15099254d918671Owen Lin TextView titleView = (TextView) v.findViewById(R.id.title); 922666ea1b28a76aeba74744148b15099254d918671Owen Lin 923666ea1b28a76aeba74744148b15099254d918671Owen Lin GalleryPickerItem iv = 924666ea1b28a76aeba74744148b15099254d918671Owen Lin (GalleryPickerItem) v.findViewById(R.id.thumbnail); 925666ea1b28a76aeba74744148b15099254d918671Owen Lin Item item = mItems.get(position); 926666ea1b28a76aeba74744148b15099254d918671Owen Lin iv.setOverlay(item.getOverlay()); 927666ea1b28a76aeba74744148b15099254d918671Owen Lin if (item.mThumbBitmap != null) { 928666ea1b28a76aeba74744148b15099254d918671Owen Lin iv.setImageBitmap(item.mThumbBitmap); 929666ea1b28a76aeba74744148b15099254d918671Owen Lin String title = item.mName + " (" + item.mCount + ")"; 930666ea1b28a76aeba74744148b15099254d918671Owen Lin titleView.setText(title); 931666ea1b28a76aeba74744148b15099254d918671Owen Lin } else { 932666ea1b28a76aeba74744148b15099254d918671Owen Lin iv.setImageResource(android.R.color.transparent); 933666ea1b28a76aeba74744148b15099254d918671Owen Lin titleView.setText(item.mName); 934666ea1b28a76aeba74744148b15099254d918671Owen Lin } 935666ea1b28a76aeba74744148b15099254d918671Owen Lin 936666ea1b28a76aeba74744148b15099254d918671Owen Lin // An workaround due to a bug in TextView. If the length of text is 937666ea1b28a76aeba74744148b15099254d918671Owen Lin // different from the previous in convertView, the layout would be 938666ea1b28a76aeba74744148b15099254d918671Owen Lin // wrong. 939666ea1b28a76aeba74744148b15099254d918671Owen Lin titleView.requestLayout(); 940666ea1b28a76aeba74744148b15099254d918671Owen Lin 941666ea1b28a76aeba74744148b15099254d918671Owen Lin return v; 942666ea1b28a76aeba74744148b15099254d918671Owen Lin } 943666ea1b28a76aeba74744148b15099254d918671Owen Lin} 944