Home | History | Annotate | Download | only in camera
      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 
     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 
     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 
    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 
    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 
    145     public static void gotoVideoMode(Activity activity) {
    146         startCameraActivity(activity, MediaStore.INTENT_ACTION_VIDEO_CAMERA,
    147                 VIDEO_CAMERA_CLASS);
    148     }
    149 
    150     public static void gotoCameraMode(Activity activity) {
    151         startCameraActivity(activity,
    152                 MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA, CAMERA_CLASS);
    153     }
    154 
    155     public static void gotoCameraImageGallery(Activity activity) {
    156         gotoGallery(activity, R.string.gallery_camera_bucket_name,
    157                 ImageManager.INCLUDE_IMAGES);
    158     }
    159 
    160     public static void gotoCameraVideoGallery(Activity activity) {
    161         gotoGallery(activity, R.string.gallery_camera_videos_bucket_name,
    162                 ImageManager.INCLUDE_VIDEOS);
    163     }
    164 
    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 
    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