Встроенная камера, используя дополнительный MediaStore.EXTRA_OUTPUT, сохраняет изображения дважды (в моей папке и по умолчанию)
В настоящее время я разрабатываю приложение, которое использует встроенную камеру.
Я вызываю этот фрагмент, нажимая кнопку:
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, который является стандартным путем.
Есть ли способ предотвратить создание встроенной камеры для сохранения изображения в папке по умолчанию?
Изменить: я думаю, что я буду использовать класс камеры напрямую
Ответы
Ответ 1
Другой способ, протестированный на 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) } );
}
Этот код был основан на сообщении: Удаление изображения галереи после снятия снимка камеры
Ответ 2
В то время как ответ от "Ilango J" дает основную идею. Я думал, что действительно напишу, как я это сделал.
Временный путь к файлу, который мы устанавливаем в aim.putExtra(), следует избегать, поскольку он является нестандартным способом для разных аппаратных средств. На HTC Desire (Android 2.2) он не работал, и я слышал, что он работает на других телефонах. Лучше всего иметь нейтральный подход, который работает везде.
Обратите внимание, что это решение (с использованием Intent) требует наличия 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) Клонировать и удалить файл. Смотрите, что я использовал Uri InputStream для чтения содержимого.
То же самое можно прочитать и из файла capturedPicFilePath
.
public void writeImageData(Uri capturedPictureUri, String capturedPicFilePath) {
// Here where the new file will be written
String newCapturedFileAbsolutePath = "something" + JPG;
// Here 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 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);
}
}
}
Ответ 3
попробуйте этот код:
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);