Встроенная камера с помощью дополнительного MediaStore.EXTRA_OUTPUT сохраняет изображения дважды (в моей папке и по умолчанию) - PullRequest
22 голосов
/ 14 июня 2011

В настоящее время я занимаюсь разработкой приложения, в котором используется встроенная камера. Я вызываю этот фрагмент, нажав кнопку:

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 напрямую

Ответы [ 3 ]

12 голосов
/ 30 января 2012

Другой способ, протестированный на Android 2.1, это взять идентификатор или абсолютный путь последнего изображения галереи, затем вы можете удалить дублированное изображение.

Это можно сделать так:

/**
 * 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) } );
}

Этот код был основан на посте: Удаление изображения галереи после того, как камера сделала намеренную фотографию

9 голосов
/ 20 августа 2011

В то время как ответ от «Иланго Дж» дает основную идею ... Я думал, что на самом деле напишу, как я это сделал. Следует избегать временного пути к файлу, который мы задали в intent.putExtra (), поскольку это нестандартный путь для разных аппаратных средств. В HTC Desire (Android 2.2) он не работал, и я слышал, что он работает на других телефонах. Лучше иметь нейтральный подход, который работает везде.

Обратите внимание, что для этого решения (с использованием намерения) требуется, чтобы SD-карта телефона была доступна и не была установлена ​​на ПК. Даже обычное приложение Камера не будет работать, когда SD-карта подключена к ПК.

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) Клонировать и удалить файл. Смотрите, что я использовал InputStream Uri для чтения содержимого. То же самое можно прочитать из файла 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);
        }
    }
}
0 голосов
/ 27 июля 2011

попробуйте этот код:

 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...