web-dev-qa-db-fra.com

Appareil photo intégré, l’utilisation de l’extra MediaStore.EXTRA_OUTPUT enregistre les images deux fois (dans mon dossier et par défaut)

Je développe actuellement une application qui utilise la caméra intégrée. J'appelle cet extrait en cliquant sur un bouton: 

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);

Après avoir pris la photo avec l'appareil photo, le fichier jpg est bien stocké dans sdcard/myFolder/myPicture.jpg, mais il est également stocké dans/sdcard/DCIM/Camera/2011-06 -14 10.36.10.jpg, qui est le chemin par défaut.

Est-il possible d'empêcher l'appareil photo intégré de stocker l'image dans le dossier par défaut?

Edit: Je pense que je vais utiliser directement la classe Camera

22
darksider

Une autre façon, testée sur Android 2.1, est de prendre l’ID ou le chemin absolu de la dernière image de la galerie, puis de supprimer l’image dupliquée.

Cela peut être fait comme ça:

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

Et pour supprimer le fichier:

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

Ce code était basé sur le message suivant: Suppression d'une image de la galerie après la prise d'une photo de l'intention de l'appareil photo

12
Derzu

Alors que la réponse de "Ilango J" fournit l’idée de base ... j’ai pensé que j’écrirais comment je l’ai fait. Le chemin du fichier temporaire que nous étions en train de définir dans intent.putExtra () devrait être évité. comme c'est un moyen non standard à travers différents matériels. Sur HTC Desire (Android 2.2), cela ne fonctionnait pas. Et j'ai entendu dire que cela fonctionnait sur d'autres téléphones. Il est préférable d'avoir une approche neutre qui fonctionne partout. 

Veuillez noter que cette solution (en utilisant l'intention) nécessite que la carte SD du téléphone soit disponible et qu'elle ne soit pas montée sur le PC. Même l'application normale de l'appareil photo ne fonctionnerait pas lorsque la carte SD est connectée à l'ordinateur. 

1) Initiez l'intention de capture de la caméra. Remarque, j'ai désactivé les écritures de fichiers temporaires (non standard sur différents matériels)

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

2) Gérez le rappel, récupérez le chemin de l'image capturée à partir de l'objet Uri et passez-le à l'étape 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) Cloner et supprimer le fichier. Voir que j'ai utilisé InputStream de Uri pour lire le contenu. La même chose peut également être lue dans le fichier de la 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);
        }
    }
}
9
Swaroop

essayez ce 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);
0
ilango j