1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera; 18 19 import android.app.Activity; 20 import android.app.AlertDialog; 21 import android.content.ActivityNotFoundException; 22 import android.content.Context; 23 import android.content.DialogInterface; 24 import android.content.DialogInterface.OnClickListener; 25 import android.content.Intent; 26 import android.net.Uri; 27 import android.os.Environment; 28 import android.os.StatFs; 29 import android.provider.MediaStore; 30 import android.provider.MediaStore.Images; 31 import android.util.Log; 32 import android.view.Menu; 33 import android.view.MenuItem; 34 import android.view.MenuItem.OnMenuItemClickListener; 35 36 import java.io.Closeable; 37 38 /** 39 * A utility class to handle various kinds of menu operations. 40 */ 41 public class MenuHelper { 42 private static final String TAG = "MenuHelper"; 43 44 public static final int INCLUDE_ALL = 0xFFFFFFFF; 45 public static final int INCLUDE_VIEWPLAY_MENU = (1 << 0); 46 public static final int INCLUDE_SHARE_MENU = (1 << 1); 47 public static final int INCLUDE_SET_MENU = (1 << 2); 48 public static final int INCLUDE_CROP_MENU = (1 << 3); 49 public static final int INCLUDE_DELETE_MENU = (1 << 4); 50 public static final int INCLUDE_ROTATE_MENU = (1 << 5); 51 public static final int INCLUDE_DETAILS_MENU = (1 << 6); 52 public static final int INCLUDE_SHOWMAP_MENU = (1 << 7); 53 54 public static final int MENU_IMAGE_SHARE = 1; 55 public static final int MENU_IMAGE_SHOWMAP = 2; 56 57 public static final int POSITION_SWITCH_CAMERA_MODE = 1; 58 public static final int POSITION_GOTO_GALLERY = 2; 59 public static final int POSITION_SWITCH_CAMERA_ID = 3; 60 61 public static final int NO_STORAGE_ERROR = -1; 62 public static final int CANNOT_STAT_ERROR = -2; 63 public static final String EMPTY_STRING = ""; 64 public static final String JPEG_MIME_TYPE = "image/jpeg"; 65 // valid range is -180f to +180f 66 public static final float INVALID_LATLNG = 255f; 67 68 /** Activity result code used to report crop results. 69 */ 70 public static final int RESULT_COMMON_MENU_CROP = 490; 71 72 private static final int NO_ANIMATION = 0; 73 private static final String CAMERA_CLASS = "com.android.camera.Camera"; 74 private static final String VIDEO_CAMERA_CLASS = "com.android.camera.VideoCamera"; 75 closeSilently(Closeable c)76 public static void closeSilently(Closeable c) { 77 if (c != null) { 78 try { 79 c.close(); 80 } catch (Throwable e) { 81 // ignore 82 } 83 } 84 } 85 confirmAction(Context context, String title, String message, final Runnable action)86 public static void confirmAction(Context context, String title, 87 String message, final Runnable action) { 88 OnClickListener listener = new OnClickListener() { 89 public void onClick(DialogInterface dialog, int which) { 90 switch (which) { 91 case DialogInterface.BUTTON_POSITIVE: 92 if (action != null) action.run(); 93 } 94 } 95 }; 96 new AlertDialog.Builder(context) 97 .setIcon(android.R.drawable.ic_dialog_alert) 98 .setTitle(title) 99 .setMessage(message) 100 .setPositiveButton(android.R.string.ok, listener) 101 .setNegativeButton(android.R.string.cancel, listener) 102 .create() 103 .show(); 104 } 105 addSwitchModeMenuItem(Menu menu, boolean switchToVideo, final Runnable r)106 static void addSwitchModeMenuItem(Menu menu, boolean switchToVideo, 107 final Runnable r) { 108 int labelId = switchToVideo 109 ? R.string.switch_to_video_lable 110 : R.string.switch_to_camera_lable; 111 int iconId = switchToVideo 112 ? R.drawable.ic_menu_camera_video_view 113 : android.R.drawable.ic_menu_camera; 114 MenuItem item = menu.add(Menu.NONE, Menu.NONE, 115 POSITION_SWITCH_CAMERA_MODE, labelId) 116 .setOnMenuItemClickListener(new OnMenuItemClickListener() { 117 public boolean onMenuItemClick(MenuItem item) { 118 r.run(); 119 return true; 120 } 121 }); 122 item.setIcon(iconId); 123 } 124 startCameraActivity(Activity activity, String action, String className)125 private static void startCameraActivity(Activity activity, String action, 126 String className) { 127 Intent intent = new Intent(action); 128 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 129 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); 130 intent.setClassName(activity.getPackageName(), className); 131 132 // Keep the camera instance for a while. 133 // This avoids re-opening the camera and saves time. 134 CameraHolder.instance().keep(); 135 136 try { 137 activity.startActivity(intent); 138 } catch (ActivityNotFoundException e) { 139 intent.setComponent(null); 140 activity.startActivity(intent); 141 } 142 activity.overridePendingTransition(NO_ANIMATION, NO_ANIMATION); 143 } 144 gotoVideoMode(Activity activity)145 public static void gotoVideoMode(Activity activity) { 146 startCameraActivity(activity, MediaStore.INTENT_ACTION_VIDEO_CAMERA, 147 VIDEO_CAMERA_CLASS); 148 } 149 gotoCameraMode(Activity activity)150 public static void gotoCameraMode(Activity activity) { 151 startCameraActivity(activity, 152 MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA, CAMERA_CLASS); 153 } 154 gotoCameraImageGallery(Activity activity)155 public static void gotoCameraImageGallery(Activity activity) { 156 gotoGallery(activity, R.string.gallery_camera_bucket_name, 157 ImageManager.INCLUDE_IMAGES); 158 } 159 gotoCameraVideoGallery(Activity activity)160 public static void gotoCameraVideoGallery(Activity activity) { 161 gotoGallery(activity, R.string.gallery_camera_videos_bucket_name, 162 ImageManager.INCLUDE_VIDEOS); 163 } 164 gotoGallery(Activity activity, int windowTitleId, int mediaTypes)165 private static void gotoGallery(Activity activity, int windowTitleId, 166 int mediaTypes) { 167 Uri target = Images.Media.EXTERNAL_CONTENT_URI.buildUpon() 168 .appendQueryParameter("bucketId", 169 ImageManager.CAMERA_IMAGE_BUCKET_ID).build(); 170 Intent intent = new Intent(Intent.ACTION_VIEW, target); 171 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 172 intent.putExtra("windowTitle", activity.getString(windowTitleId)); 173 intent.putExtra("mediaTypes", mediaTypes); 174 175 try { 176 activity.startActivity(intent); 177 } catch (ActivityNotFoundException e) { 178 Log.e(TAG, "Could not start gallery activity", e); 179 } 180 } 181 calculatePicturesRemaining()182 public static int calculatePicturesRemaining() { 183 try { 184 if (!ImageManager.hasStorage()) { 185 return NO_STORAGE_ERROR; 186 } else { 187 String storageDirectory = 188 Environment.getExternalStorageDirectory().toString(); 189 StatFs stat = new StatFs(storageDirectory); 190 final int PICTURE_BYTES = 1500000; 191 float remaining = ((float) stat.getAvailableBlocks() 192 * (float) stat.getBlockSize()) / PICTURE_BYTES; 193 return (int) remaining; 194 } 195 } catch (Exception ex) { 196 // if we can't stat the filesystem then we don't know how many 197 // pictures are remaining. it might be zero but just leave it 198 // blank since we really don't know. 199 Log.e(TAG, "Fail to access sdcard", ex); 200 return CANNOT_STAT_ERROR; 201 } 202 } 203 } 204