将点击的图像保存到自定义文件夹(最好是应用内部),而不是图库

我正在尝试将相机function整合到应用程序中。 我可以将图片保存到自定义文件夹中,但问题是图像被保存到相机文件夹(相机图片保存的地方)。 因此,我拍摄的每张图片都有重复的图像。 我不希望这样。 以下是代码:

public class PhotoIntentActivity extends Activity { private static final int ACTION_TAKE_PHOTO_B = 1; private static final String BITMAP_STORAGE_KEY = "viewbitmap"; private static final String IMAGEVIEW_VISIBILITY_STORAGE_KEY = "imageviewvisibility"; private ImageView mImageView; private Bitmap mImageBitmap; private String mCurrentPhotoPath; private static final String JPEG_FILE_PREFIX = "IMG_"; private static final String JPEG_FILE_SUFFIX = ".jpg"; private AlbumStorageDirFactory mAlbumStorageDirFactory = null; /* Photo album for this application */ private String getAlbumName() { return getString(R.string.album_name); } private File getAlbumDir() { File storageDir = null; if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState())) { storageDir = mAlbumStorageDirFactory .getAlbumStorageDir(getAlbumName(), getApplicationContext()); if (storageDir != null) { if (!storageDir.mkdirs()) { if (!storageDir.exists()) { Log.d("CameraSample", "failed to create directory"); return null; } } } } else { Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE."); } return storageDir; } private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") .format(new Date()); String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_"; File albumF = getAlbumDir(); File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumF); return imageF; } private File setUpPhotoFile() throws IOException { File f = createImageFile(); mCurrentPhotoPath = f.getAbsolutePath(); return f; } private void setPic() { /* There isn't enough memory to open up more than a couple camera photos */ /* So pre-scale the target bitmap into which the file is decoded */ /* Get the size of the ImageView */ int targetW = mImageView.getWidth(); int targetH = mImageView.getHeight(); /* Get the size of the image */ BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); int photoW = bmOptions.outWidth; int photoH = bmOptions.outHeight; /* Figure out which way needs to be reduced less */ int scaleFactor = 1; if ((targetW > 0) || (targetH > 0)) { scaleFactor = Math.min(photoW / targetW, photoH / targetH); } /* Set bitmap options to scale the image decode target */ bmOptions.inJustDecodeBounds = false; bmOptions.inSampleSize = scaleFactor; bmOptions.inPurgeable = true; /* Decode the JPEG file into a Bitmap */ Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions); /* Associate the Bitmap to the ImageView */ mImageView.setImageBitmap(bitmap); mImageView.setVisibility(View.VISIBLE); } private void galleryAddPic() { Intent mediaScanIntent = new Intent( "android.intent.action.MEDIA_SCANNER_SCAN_FILE"); File f = new File(mCurrentPhotoPath); System.out.println(mCurrentPhotoPath); Uri contentUri = Uri.fromFile(f); mediaScanIntent.setData(contentUri); this.sendBroadcast(mediaScanIntent); } private void dispatchTakePictureIntent(int actionCode) { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); switch (actionCode) { case ACTION_TAKE_PHOTO_B: File f = null; try { f = setUpPhotoFile(); mCurrentPhotoPath = f.getAbsolutePath(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f)); } catch (IOException e) { e.printStackTrace(); f = null; mCurrentPhotoPath = null; } break; default: break; } // switch startActivityForResult(takePictureIntent, actionCode); } private void handleBigCameraPhoto() { if (mCurrentPhotoPath != null) { setPic(); galleryAddPic(); mCurrentPhotoPath = null; } } Button.OnClickListener mTakePicOnClickListener = new Button.OnClickListener() { @Override public void onClick(View v) { dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B); } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mImageView = (ImageView) findViewById(R.id.imageView1); mImageBitmap = null; Button picBtn = (Button) findViewById(R.id.btnIntend); setBtnListenerOrDisable(picBtn, mTakePicOnClickListener, MediaStore.ACTION_IMAGE_CAPTURE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { mAlbumStorageDirFactory = new FroyoAlbumDirFactory(); } else { mAlbumStorageDirFactory = new BaseAlbumDirFactory(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case ACTION_TAKE_PHOTO_B: { if (resultCode == RESULT_OK) { handleBigCameraPhoto(); } break; } } } // Some lifecycle callbacks so that the image can survive orientation change @Override protected void onSaveInstanceState(Bundle outState) { outState.putParcelable(BITMAP_STORAGE_KEY, mImageBitmap); outState.putBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY, (mImageBitmap != null)); super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mImageBitmap = savedInstanceState.getParcelable(BITMAP_STORAGE_KEY); mImageView.setImageBitmap(mImageBitmap); mImageView .setVisibility(savedInstanceState .getBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY) ? ImageView.VISIBLE : ImageView.INVISIBLE); } /** * Indicates whether the specified action can be used as an intent. This * method queries the package manager for installed packages that can * respond to an intent with the specified action. If no suitable package is * found, this method returns false. * http://android-developers.blogspot.com/2009/01/can-i-use-this-intent.html * * @param context * The application's environment. * @param action * The Intent action to check for availability. * * @return True if an Intent with the specified action can be sent and * responded to, false otherwise. */ public static boolean isIntentAvailable(Context context, String action) { final PackageManager packageManager = context.getPackageManager(); final Intent intent = new Intent(action); List list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); return list.size() > 0; } private void setBtnListenerOrDisable(Button btn, Button.OnClickListener onClickListener, String intentName) { if (isIntentAvailable(this, intentName)) { btn.setOnClickListener(onClickListener); } else { btn.setText(getText(R.string.cannot).toString() + " " + btn.getText()); btn.setClickable(false); } } public final class FroyoAlbumDirFactory extends AlbumStorageDirFactory { @Override public File getAlbumStorageDir(String albumName, Context context) { // TODO Auto-generated method stub return new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),albumName); } } 

提前致谢。

保存在自定义文件中后,您可以删除该文件。 如果您不确定相机所用文件的名称,您可以查看时间戳,或者,如果您愿意发疯,可以使用FileObserver等待文件完成写入,然后再将其删除(如果并发是一个问题而且发生了一些不好的事情。)

做了一些研究之后,我发现这个答案发布在这里: 双重保存图像

最佳解决方案保存在应用程序缓存目录下,该目录只能从您的应用程序上下文context.getCacheDir()

或者使用这个类并调用ExternalStorage.getSDCacheDir(context,"dirname");

 import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import android.content.Context; public class ExternalStorage { // Convention for external storage path used by Android 2.2. private static final String EXT_STORAGE_ROOT_PREFIX = "/Android/data/"; private static final String EXT_STORAGE_ROOT_SUFFIX = "/files/"; private static StringBuilder sStoragePath = new StringBuilder(); private static final String ALTERNATE_SDCARD_MOUNTS[] = { "/emmc", "/sdcard/ext_sd", // Newer (2011) HTC devices (Flyer, Rezound) "/sdcard-ext", // Some Motorola devices (RAZR) "/sdcard/sd", // Older Samsung Galaxy S (Captivate) "/sdcard/sdcard" // Archos tablets }; /** * Create given directory on sd card application cache Directory. * * @param context * @param dirName * @return created cache directory file, if not created return null. */ public static File getSDCacheDir(Context context, String dirName) { File cacheDir = null; // Check to see if SD Card is mounted and read/write accessible if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment .getExternalStorageState())) { // Get the directory on the SD card to store content // Attempt to use getExternalFilesDir() if we are on Android 2.2 or newer // Data stored in this location will auto-delete with app uninstall Method getExternalFilesDirMethod = null; try { getExternalFilesDirMethod = Context.class.getMethod( "getExternalFilesDir", String.class); cacheDir = (File) getExternalFilesDirMethod.invoke(context, dirName); } catch (NoSuchMethodException e) { // Android 2.1 and earlier - use old APIs cacheDir = buildCacheDirPath(context, android.os.Environment.getExternalStorageDirectory(), dirName); } catch (IllegalArgumentException e) { cacheDir = buildCacheDirPath(context, android.os.Environment.getExternalStorageDirectory(), dirName); } catch (IllegalAccessException e) { cacheDir = buildCacheDirPath(context, android.os.Environment.getExternalStorageDirectory(), dirName); } catch (InvocationTargetException e) { cacheDir = buildCacheDirPath(context, android.os.Environment.getExternalStorageDirectory(), dirName); } } if (cacheDir == null) { // Attempting to find the default external storage was a failure. // Look for another suitable external filesystem where we can store // our crap for (int i = 0; i < ALTERNATE_SDCARD_MOUNTS.length; i++) { File alternateDir = new File(ALTERNATE_SDCARD_MOUNTS[i]); if (alternateDir.exists() && alternateDir.isDirectory() && alternateDir.canRead() && alternateDir.canWrite()) { cacheDir = buildCacheDirPath(context, alternateDir, dirName); break; } } } // Attempt to create folder on external storage if it does not exist if (cacheDir != null && !cacheDir.exists()) { if (!cacheDir.mkdirs()) { cacheDir = null; // Failed to create folder } } // Fall back on internal cache as a last resort if (cacheDir == null) { cacheDir = new File(context.getCacheDir() + File.separator + dirName); cacheDir.mkdirs(); } return cacheDir; } 

有两种方法

  1. 相机意图
  2. 定制相机

您正在使用Camera Intent。

新意图(MediaStore.ACTION_IMAGE_CAPTURE);

MediaStore.ACTION_IMAGE_CAPTURE – 用于从现有相机应用程序请求图像的意图操作types。

MediaStore.EXTRA_OUTPUT – 此设置需要一个Uri对象,指定您要保存图片的路径和文件名

如何保存媒体文件 ?

 private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100; private Uri fileUri; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // create Intent to take a picture and return control to the calling application Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name // start the image capture Intent startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); } 

请正确遵循上述说明以避免此类重复。

第二个选项是您需要使用自定义相机 。

请阅读这篇完整的文章 ,了解相机function。

暗示:

startActivityForResult()中编写代码, 将图片从相机文件夹 移动到自定义文件夹,而不是将图像保存在自定义文件夹中。

希望这可能会给你一些有用的信息。

将此图像保存在自定义文件夹中后,从相机文件夹中删除图像