内置相机,使用额外的MediaStore.EXTRA_OUTPUT将图片存储两次(在我的文件夹中,在默认情况下)

发布于 2024-11-15 14:07:38 字数 762 浏览 0 评论 0原文

我目前正在开发一个使用内置相机的应用程序。 我通过单击按钮来调用此片段:

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String path = Environment.getExternalStorageDirectory().getAbsolutePath();
path += "/myFolder/myPicture.jpg";
File file = new File( path );
//file.mkdirs();
Uri outputFileUri = Uri.fromFile( file );
//String absoluteOutputFileUri = file.getAbsolutePath();

intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);

用相机拍照后,jpg 良好存储在 sdcard/myFolder/myPicture.jpg 中,但它也存储在 /sdcard/DCIM/Camera/2011-06-14 10.36.10.jpg 中,这是默认路径。

有没有办法阻止内置相机将图片存储在默认文件夹中?

编辑:我想我会直接使用 Camera 类

I'm currently developing an app which uses the built-in Camera.
I call this snippet by clicking a button :

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String path = Environment.getExternalStorageDirectory().getAbsolutePath();
path += "/myFolder/myPicture.jpg";
File file = new File( path );
//file.mkdirs();
Uri outputFileUri = Uri.fromFile( file );
//String absoluteOutputFileUri = file.getAbsolutePath();

intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);

After taking the picture with the camera, the jpg is well stored in sdcard/myFolder/myPicture.jpg, but it is also stored in /sdcard/DCIM/Camera/2011-06-14 10.36.10.jpg, which is the default path.

Is there a way to prevent the built-in Camera to store the picture in the default folder?

Edit : I think I will use the Camera class directly

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

没有心的人 2024-11-22 14:07:38

另一种方法,在android 2.1上测试,是获取图库最后一张图像的ID或绝对路径,然后你可以删除重复的图像。

可以这样做:

/**
 * Gets the last image id from the media store
 * @return
 */
private int getLastImageId(){
    final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
    final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
    Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
    if(imageCursor.moveToFirst()){
        int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
        String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
        Log.d(TAG, "getLastImageId::id " + id);
        Log.d(TAG, "getLastImageId::path " + fullPath);
        imageCursor.close();
        return id;
    }else{
        return 0;
    }
}

并删除文件:

private void removeImage(int id) {
   ContentResolver cr = getContentResolver();
   cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media._ID + "=?", new String[]{ Long.toString(id) } );
}

此代码基于帖子: 在拍摄意图照片后删除图库图像

Another way, tested on android 2.1, is take the ID or Absolute path of the gallery last image, then you can delete the duplicated image.

It can be done like that:

/**
 * Gets the last image id from the media store
 * @return
 */
private int getLastImageId(){
    final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
    final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
    Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
    if(imageCursor.moveToFirst()){
        int id = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
        String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
        Log.d(TAG, "getLastImageId::id " + id);
        Log.d(TAG, "getLastImageId::path " + fullPath);
        imageCursor.close();
        return id;
    }else{
        return 0;
    }
}

And to remove the file:

private void removeImage(int id) {
   ContentResolver cr = getContentResolver();
   cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media._ID + "=?", new String[]{ Long.toString(id) } );
}

This code was based on the post: Deleting a gallery image after camera intent photo taken

趁年轻赶紧闹 2024-11-22 14:07:38

虽然“Ilango J”的答案提供了基本的想法..我想我实际上应该写下我实际上是如何做到的。
应避免我们在intent.putExtra() 中设置的临时文件路径,因为它是跨不同硬件的非标准方式。在 HTC Desire (Android 2.2) 上它不起作用,而且我听说它在其他手机上也起作用。最好采用一种在任何地方都适用的中立方法。

请注意,此解决方案(使用 Intent)要求手机的 SD 卡可用且未安装到 PC 上。当 SD 卡连接到 PC 时,即使是普通的相机应用程序也无法运行。

1) 启动相机捕捉意图。注意,我禁用了临时文件写入(跨不同硬件的非标准)

    Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(camera , 0);

2) 处理回调并从 Uri 对象检索捕获的图片路径并将其传递到步骤#3

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case CAPTURE_PIC: {
        if (resultCode == RESULT_OK && data != null) {
            Uri capturedImageUri = data.getData();
            String capturedPicFilePath = getRealPathFromURI(capturedImageUri);
            writeImageData(capturedImageUri, capturedPicFilePath);
            break;
        }
    }
    }
}

public String getRealPathFromURI(Uri contentUri) {
    String[] projx = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(contentUri, projx, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

3) 克隆并删除文件。看到我使用了Uri的InputStream来读取内容。
同样的内容也可以从capturedPicFilePath的文件中读取。

public void writeImageData(Uri capturedPictureUri, String capturedPicFilePath) {

    // Here's where the new file will be written
    String newCapturedFileAbsolutePath = "something" + JPG;

    // Here's how to get FileInputStream Directly.
    try {
        InputStream fileInputStream = getContentResolver().openInputStream(capturedPictureUri);
        cloneFile(fileInputStream, newCapturedFileAbsolutePath);
    } catch (FileNotFoundException e) {
        // suppress and log that the image write has failed. 
    }

    // Delete original file from Android's Gallery
    File capturedFile = new File(capturedPicFilePath);
    boolean isCapturedCameraGalleryFileDeleted = capturedFile.delete();
}

  public static void cloneFile(InputStream currentFileInputStream, String newPath) {
    FileOutputStream newFileStream = null;

    try {

        newFileStream = new FileOutputStream(newPath);

        byte[] bytesArray = new byte[1024];
        int length;
        while ((length = currentFileInputStream.read(bytesArray)) > 0) {
            newFileStream.write(bytesArray, 0, length);
        }

        newFileStream.flush();

    } catch (Exception e) {
        Log.e("Prog", "Exception while copying file " + currentFileInputStream + " to "
                + newPath, e);
    } finally {
        try {
            if (currentFileInputStream != null) {
                currentFileInputStream.close();
            }

            if (newFileStream != null) {
                newFileStream.close();
            }
        } catch (IOException e) {
            // Suppress file stream close
            Log.e("Prog", "Exception occured while closing filestream ", e);
        }
    }
}

While the answer from "Ilango J" provides the basic idea.. I thought I'd actually write in how I actually did it.
The temporary file path that we were setting in intent.putExtra() should be avoided as it's a non standard way across different hardwares. On HTC Desire (Android 2.2) it did not work, And i've heard it works on other phones. It's best to have a neutral approach which works every where.

Please note that this solution (using the Intent) requires that the phone's SD Card is available and is not mounted onto the PC. Even the normal Camera app wouldn't work when the SD Card is connected to the PC.

1) Initiate the Camera Capture intent. Note, I disabled temporary file writes (non-standard across different hardware)

    Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(camera , 0);

2) Handle callback and retrieve the captured picture path from the Uri object and pass it to step#3

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case CAPTURE_PIC: {
        if (resultCode == RESULT_OK && data != null) {
            Uri capturedImageUri = data.getData();
            String capturedPicFilePath = getRealPathFromURI(capturedImageUri);
            writeImageData(capturedImageUri, capturedPicFilePath);
            break;
        }
    }
    }
}

public String getRealPathFromURI(Uri contentUri) {
    String[] projx = { MediaStore.Images.Media.DATA };
    Cursor cursor = managedQuery(contentUri, projx, null, null, null);
    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    return cursor.getString(column_index);
}

3) Clone and delete the file. See that I used the Uri's InputStream to read the content.
The same can be read from the File of the capturedPicFilePath too.

public void writeImageData(Uri capturedPictureUri, String capturedPicFilePath) {

    // Here's where the new file will be written
    String newCapturedFileAbsolutePath = "something" + JPG;

    // Here's how to get FileInputStream Directly.
    try {
        InputStream fileInputStream = getContentResolver().openInputStream(capturedPictureUri);
        cloneFile(fileInputStream, newCapturedFileAbsolutePath);
    } catch (FileNotFoundException e) {
        // suppress and log that the image write has failed. 
    }

    // Delete original file from Android's Gallery
    File capturedFile = new File(capturedPicFilePath);
    boolean isCapturedCameraGalleryFileDeleted = capturedFile.delete();
}

  public static void cloneFile(InputStream currentFileInputStream, String newPath) {
    FileOutputStream newFileStream = null;

    try {

        newFileStream = new FileOutputStream(newPath);

        byte[] bytesArray = new byte[1024];
        int length;
        while ((length = currentFileInputStream.read(bytesArray)) > 0) {
            newFileStream.write(bytesArray, 0, length);
        }

        newFileStream.flush();

    } catch (Exception e) {
        Log.e("Prog", "Exception while copying file " + currentFileInputStream + " to "
                + newPath, e);
    } finally {
        try {
            if (currentFileInputStream != null) {
                currentFileInputStream.close();
            }

            if (newFileStream != null) {
                newFileStream.close();
            }
        } catch (IOException e) {
            // Suppress file stream close
            Log.e("Prog", "Exception occured while closing filestream ", e);
        }
    }
}
烟凡古楼 2024-11-22 14:07:38

试试这个代码:

 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String path = Environment.getExternalStorageDirectory().getAbsolutePath();
path += "/myFolder/myPicture.jpg";
File file = new File( path );
//file.mkdirs();
Uri outputFileUri = Uri.fromFile( file );
//String absoluteOutputFileUri = file.getAbsolutePath();

intent.putExtra("output", outputFileUri);
startActivityForResult(intent, 0);

try this code:

 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

String path = Environment.getExternalStorageDirectory().getAbsolutePath();
path += "/myFolder/myPicture.jpg";
File file = new File( path );
//file.mkdirs();
Uri outputFileUri = Uri.fromFile( file );
//String absoluteOutputFileUri = file.getAbsolutePath();

intent.putExtra("output", outputFileUri);
startActivityForResult(intent, 0);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文