Камера и формат имён файлов

Мною было замечено, что в ванильном андроиде (в отличии от, например, правильного в этом плане Галереи от Sense) формат хранения файлов фотографий не соответствует спецификациям, которые требуют хранить фотографии с адресом по шаблону /DCIM/123ABCD/ABCD1234.jpg, андроид же (2.3 в том числе) делает пути вида /DCIM/Camera/IMG_<дата>_<время>.jpg, что не совпадает со стандартом, из-за чего iPhoto не видит контента для импорта.

Кстати, этот дефект опубликован в основном баг-трекере от 11.06.2009, но у него очень мало голосов, поэтому он успешно игнорируется. Если вы заинтересованы в его решении, не поленитесь также поставить звёздочку :)

Поехали!
Что ж, система открытая — решено исправить. Синхронизируем источники, открываем редактор, импортируем готовый проект и начинаем править. Внести требуется лишь три изменения: путь до фотографий, шаблон имени для фотографий, шаблон имени для видеозаписей. Не отвлекаясь на посторонние темы, даю код для замены:

// 1) com.android.camera.ImageManager.java:129

public static final String CAMERA_IMAGE_BUCKET_NAME =
	Environment.getExternalStorageDirectory().toString()
	+ "/DCIM/100ANDRO";


//2) com.android.camera.Camera.java:871

private String createName(long dateTaken) {
	int n = 1, max = 0;
	for(File file:	// go through all jpg's
		new File(ImageManager.CAMERA_IMAGE_BUCKET_NAME).listFiles(new FilenameFilter() {
			@Override public boolean accept(File dir, String filename) {
				return filename.toLowerCase().endsWith(".jpg");
			}
		})
	){
		try{	// try to search maximum
			n = Integer.parseInt(file.getName().substring(4, 8));
			if(n>max) max = n;
		}catch (Exception ignored) {
		}
	}
	return String.format("IMAG%04d", max+1);
}


//3) com.android.camera.VideoCamera.java:252

private String createName(long dateTaken) {
	int n = 1, max = 0;
	for(File file:	// go through all 3gp's
		new File(ImageManager.CAMERA_IMAGE_BUCKET_NAME).listFiles(new FilenameFilter() {
			@Override public boolean accept(File dir, String filename) {
				return filename.toLowerCase().endsWith(".3gp");
			}
		})
	){
		try{	// try to search maximum
			n = Integer.parseInt(file.getName().substring(5, 9));
			if(n>max) max = n;
		}catch (Exception ignored) {
		}
	}
	return String.format("VIDEO%04d", max+1);
}

Чтобы заменить системный пакет на устройстве, необходимо либо удалить оригинал, либо сделать вид, что мы обновляем пакет, положив пакет в /data/app/com.android.camera-1.apk, тогда система будет использовать «новый» пакет. Даю ссылки на исходные коды (из репозитория AOSP) и собранный мной бинарник (подписан дебаг-сертификатом):

Исходники (590кб)
Бинарник (541кб)

 

Финальный штрих:
Чтобы теперь и Галерея начала распознавать нашу папку 100ANDRO как папку хранения фотографий и корректно сортировала файлы в ней (в обратном порядке, сначала свежие файлы), нужно поправить и её, благо исходный код также доступен, а исправлений буквально пара:

// 1) com.cooliris.media.ImageManager.java:61

	public static final String CAMERA_IMAGE_BUCKET_NAME = Environment.getExternalStorageDirectory().toString() + "/DCIM/100ANDRO";


// 2) com.cooliris.media.LocalDataSource.java:46

	public static final String CAMERA_STRING = "100ANDRO";

Также, коды и результат:

Исходники (938кб)
Бинарник (680кб)

 

Андроид , , ,

3 comments


  1. Влад

    почему-то камера снимает фото искаженным(

    • ArtRoman

      Странно, ведь это «ванильная» камера, т.е. оригинальная из исходных кодов андроида. Имеется более свежая, майская сборка камеры и галереи, которыми я сам пользуюсь в данный момент на Desire. Какой у вас аппарат?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *