Урок 131. Камера. Используем системное приложение

Обсуждение уроков
Аватара пользователя
rezak90
Сообщения: 3422
Зарегистрирован: 26 июн 2012, 13:22
Откуда: UA
Контактная информация:

Re: Урок 131. Камера. Используем системное приложение

Сообщение rezak90 » 17 ноя 2013, 13:07

IgNa писал(а):Во-первых, как уже говорил snowkam изображение сохраняется и в папку Picture и туда где хранятся все фотки с фотика ( не знаю как он с этим справился )
Во-вторых, лично у меня .. при записи видео, после нажатия кнопки стоп, приложение вылетает на всех девайсах, но видеофайл создается в папке Picture

Эти два факта делают невозможным использовать столь полезный код
Если кто знает как исправить, не дайте никому вас остановить
если вылетает то нужно лог ошибок выкладывать, 125 сообщений на форуме и до сих пор приходится выпрашивать логи
R.id.team
Политика на форуме запрещена

Аватара пользователя
IgNa
Сообщения: 345
Зарегистрирован: 30 сен 2013, 12:18

Re: Урок 131. Камера. Используем системное приложение

Сообщение IgNa » 17 ноя 2013, 15:12

Я немного ошибся - при нажатии кнопки стоп при записи видео, ошибка возникает не в ЭТОМ приложении, а в приложении камера ( на телефоне либо планшете)
Таким образом никаких логов нет

Но нерабочесть кода остается, хотел бы посмореть на людей у которых данный код работает на реальных устройствах,
а не в эмуляторах, уверен что таких почти нет. Исправьте пожалуйста свой недочет... люди страдают, в африке дети умирают от голода. Эффект бабочки)
Изображение


httpdispatch
Сообщения: 3
Зарегистрирован: 31 июл 2012, 10:38

Re: Урок 131. Камера. Используем системное приложение

Сообщение httpdispatch » 25 ноя 2013, 12:00

SevenXP писал(а):Кто может уже подскажет, хотя этот вопрос не к это му уроку.

Делал приложение собственную фото камеру. Вот 2 устройство 2.3 андроид и планшет 4.0.4 вернул мне макс. разрешение фото. Для телефона 2.3 2500*1600 для планшета уже не помню но точно не размер экрана. Но на HTC 4.0.3 у которого была возможность делать фото в 3д возвращает постоянно фотку с размером экрана. Переключатель на HTC стоял на 2D и пробовал на 3D и всегда был размер фотки как и экрана. Но это же приложение на 2-х других дали нужный мне результат. Кто знает в чем может быть причина?
С HTC могут быть проблемы. Некоторые модели игнорируют настройки пути (EXTRA_OUTPUT) в Camera Intent или возвращают не пойми что. Ссылка по теме http://stackoverflow.com/a/6600148/527759. Как обойти баг можно почитать тут http://thanksmister.com/2012/03/16/andr ... ra_intent/
snowkam писал(а):Почему то когда я делаю фотографию, фотография записывается и в обычную папку Camera и в папку которую мы создаем программно!!!
1. Как исправить этот баг?
Это может быть неприятная особенность некоторых телефонов. Выше я привел ссылки
snowkam писал(а): 2. Как программно указать папку которую использует системное приложение Camera? и как после того как сделал снимок узнать имя файла?
Может, лучше задать имя изначально
IgNa писал(а):Во-первых, как уже говорил snowkam изображение сохраняется и в папку Picture и туда где хранятся все фотки с фотика ( не знаю как он с этим справился )
...
Если кто знает как исправить, не дайте никому вас остановить
Попробуйте фиксы по ссылке выше.

Как это пытался обойти я. К сожалению не ручаюсь за 100% работоспособность, но некоторые баги это исправило. Выглядит как нагромождение костылей, но другого способа я не нашел.

Код: Выделить всё

mUploadImageFile = getNextFileName("upload_");
// this is a hack for some
// devices taken from here
// http://thanksmister.com/2012/03/16/android_null_data_camera_intent/
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE,
        mUploadImageFile.getName());
values.put(MediaStore.Images.Media.DATA,
        mUploadImageFile.getAbsolutePath());

Intent intent = new Intent(
        MediaStore.ACTION_IMAGE_CAPTURE);

fileUri = getActivity()
        .getContentResolver()
        .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                values);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

startActivityForResult(intent, REQUEST_CAMERA);
Если снимок не был сделан, нужно удалить fileUri из галереи

Код: Выделить всё

void removeGalleryEntryForCurrentFile()
{
    int rowsDeleted = TroveboxApplication.getContext().getContentResolver()
            .delete(fileUri, null, null);
}
Если снимок сделан, желательно обновить некоторые данные в галерее, такие как размер

Код: Выделить всё

/**
 * Calculate the image size for the given file name.
 * 
 * @param filename
 * @return
 */
public static BitmapFactory.Options calculateImageSize(String filename) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(filename, options);
    return options;
}
void updateingGalleryPictureSize()
{
    int sdk = android.os.Build.VERSION.SDK_INT;
    if (sdk < android.os.Build.VERSION_CODES.HONEYCOMB)
    {
        return;
    }

    BitmapFactory.Options options = calculateImageSize(mUploadImageFile
            .getAbsolutePath());
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.WIDTH, options.outWidth);
    values.put(MediaStore.Images.Media.HEIGHT, options.outHeight);
    int rowsUpdated = TroveboxApplication.getContext().getContentResolver()
            .update(fileUri, values, null, null);
}
Код onActivityResult

Код: Выделить всё

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_CAMERA:
            if (resultCode == RESULT_OK) {
                updateingGalleryPictureSize();
                setSelectedImageFile();
            } else {
                removeGalleryEntryForCurrentFile();
                mUploadImageFile = null;
            }
            break;
        default:
            break;
    }
}

Tuhlom
Сообщения: 6
Зарегистрирован: 22 ноя 2012, 18:41

Re: Урок 131. Камера. Используем системное приложение

Сообщение Tuhlom » 16 дек 2013, 13:10

У меня такая же проблема, как и у NitrogenW.
NitrogenW писал(а):Здравствуйте! у меня фотография всегда получается повернутой в ландшафтный режим: делаю в портретном -- итоговое изображение повернуто на 90 граусов :( Что можно с этим сделать?

Код: Выделить всё

intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
не помогло
Независимо от того, в какой ориентации я делаю фотографию, в ImageView всегда выводится картинка в ландшафтном режиме. Причём, если я нахожу фотку в проводнике и открываю её встроенным просмотрщиком, то она показывается в правильной ориентации. Есть какой-то способ определять ориентацию получившейся фотки для её правильного отображения в ImageView?

Tuhlom
Сообщения: 6
Зарегистрирован: 22 ноя 2012, 18:41

Re: Урок 131. Камера. Используем системное приложение

Сообщение Tuhlom » 16 дек 2013, 14:17

Много гуглил и, к своему удивлению, во многих туториалах встречал в комментариях такой же вопрос, почему-то оставляемый без внимания. Только один добрый человек нашёл решение, которое, кстати, довольно-таки простое. Скомпилировав несколько ответов, получил такую парочку методов:

Код: Выделить всё

	  private void setPic(ImageView iv) {
		    // Get the dimensions of the View
                    int targetW = mImageView.getWidth();
                    int targetH = mImageView.getHeight();
		  
		    // Get the dimensions of the bitmap
		    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
		    bmOptions.inJustDecodeBounds = true;
		    BitmapFactory.decodeFile(imageUri.getPath(), bmOptions);
		    int photoW = bmOptions.outWidth;
		    int photoH = bmOptions.outHeight;
		  
		    // Determine how much to scale down the image
		    int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
		  
		    // Decode the image file into a Bitmap sized to fill the View
		    bmOptions.inJustDecodeBounds = false;
		    bmOptions.inSampleSize = scaleFactor;
		    bmOptions.inPurgeable = true;
		  
		    Bitmap bitmap = BitmapFactory.decodeFile(imageUri.getPath(), bmOptions);

            ExifInterface ei;
			try {
		    ei = new ExifInterface(imageUri.getPath());
	            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
	            Log.d(TAG, "ei = " + ei.toString());
	            Log.d(TAG, "orientation = " + orientation);
	            switch(orientation) {
	                case ExifInterface.ORIENTATION_ROTATE_90:
	                	bitmap = rotateImage(bitmap, 90);
	                    break;
	                case ExifInterface.ORIENTATION_ROTATE_180:
	                	bitmap = rotateImage(bitmap, 180);
	                    break;
	                case ExifInterface.ORIENTATION_ROTATE_270:
	                	bitmap = rotateImage(bitmap, 270);
	                    break;
	            }
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		    iv.setImageBitmap(bitmap);
		    
		}

	  private Bitmap rotateImage(Bitmap bitmap, int degrees){
              Matrix matrix = new Matrix();
              matrix.postRotate(degrees);
              bitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
              return bitmap;
	  }
	 
imageUri - Uri к сохранённой ранее фотке

Надеюсь, кому-нибудь это поможет

0zzy
Сообщения: 1
Зарегистрирован: 04 фев 2014, 00:17

Re: Урок 131. Камера. Используем системное приложение

Сообщение 0zzy » 04 фев 2014, 00:24

Здравствуйте!
Подскажите пожалуйста, в уроке написано что при работе с фото в активити onActivityResult intent возвращается пустой (если используется путь для сохранения фото не по умолчанию). Как тогда получить само фото? Сохранять uri и по нему искать? Извините, если вопрос не слишком умный)

snowkam
Сообщения: 162
Зарегистрирован: 21 мар 2013, 11:22

Re: Урок 131. Камера. Используем системное приложение

Сообщение snowkam » 10 фев 2014, 10:19

Добрый день.
Может кто подскажет, как узнать путь в читабельном формате?
Дело в том что при получении пути к изображению что в камере что в галереи он выглядит так "content://media/external/images/media/15"
с путем такого вида для работы с битмапами вполне подходит и работает хорошо.
Но если я пытаюсь скажем переименовать файл то нечего не выходит в добавок ко всему ошибок не выдает ошибку удалось обнаружить вот этим способом
if (oldFile.renameTo(newFile)) {
Log.d("TAG", "SobitieAdd saveFile " + "no error");
} else Log.d("TAG", "SobitieAdd saveFile " + "error");

Выше я задавал такой вопрос и сам нашел на него ответ

Uri selectedImage = imageReturnedIntent.getData();
Cursor cursor = getContentResolver().query(selectedImage, null, null, null, null);
cursor.moveToFirst();
int columnIndexData = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
filePath = cursor.getString(columnIndexData);
cursor.close();

но этот метод явно не хочет работать на некоторых версиях
может есть другой способ????

Realist
Сообщения: 134
Зарегистрирован: 08 фев 2014, 18:15

Re: Урок 131. Камера. Используем системное приложение

Сообщение Realist » 14 мар 2014, 15:37

"getData вернул null, хотя хелп обещал, что там будет путь к файлу"

А где можно почитать этот хелп?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 131. Камера. Используем системное приложение

Сообщение damager82 » 14 мар 2014, 23:40

Realist писал(а):"getData вернул null, хотя хелп обещал, что там будет путь к файлу"

А где можно почитать этот хелп?
Тут он - http://developer.android.com/guide/topi ... amera.html
MediaStore.EXTRA_OUTPUT - This setting requires a Uri object specifying a path and file name where you'd like to save the picture. This setting is optional but strongly recommended. If you do not specify this value, the camera application saves the requested picture in the default location with a default name, specified in the returned intent's Intent.getData() field.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

zuko
Сообщения: 1
Зарегистрирован: 13 апр 2014, 18:30

Re: Урок 131. Камера. Используем системное приложение

Сообщение zuko » 13 апр 2014, 19:20

Всем привет.
Насчёт дублирования снимка (своя директория + стандартная), если кому ещё надо. Просто чтобы сэкономить ваше время.
Сразу скажу, что проконтролировать этот баг на всех девайсах невозможно и универсального решения похоже нет.

Почему это происходит.

Всё зависит от системного приложения работы с камерой. Даже если мы явно отправим ему путь для сохранения снимка, например даже вот так (вариант от httpdispatch):

Код: Выделить всё

mUploadImageFile = getNextFileName("upload_"); 
// this is a hack for some 
// devices taken from here 
// http://thanksmister.com/2012/03/16/android_null_data_camera_intent/ 
ContentValues values = new ContentValues(); 
values.put(MediaStore.Images.Media.TITLE, 
        mUploadImageFile.getName()); 
values.put(MediaStore.Images.Media.DATA, 
        mUploadImageFile.getAbsolutePath()); 
 
Intent intent = new Intent( 
        MediaStore.ACTION_IMAGE_CAPTURE); 
 
fileUri = getActivity() 
        .getContentResolver() 
        .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
                values); 
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); 
 
startActivityForResult(intent, REQUEST_CAMERA); 
системное приложение (существенное множество их разновидностей) создаст дефолтный снимок ещё и в своей дефолтной директории.

Как бы можно было это обойти.

1. Удалить дубликат снимка в onActivityResult, вытащив Uri из intent.getData().
Может не получиться по следующим причинам:

- Ещё одно множество системных приложений просто возвращает NULL в intent.getData() (по идее это нормально, если вы явно указываете MediaStore.EXTRA_OUTPUT, но возможны исключения в обе стороны).
- В intent.getData() может оказаться URI, который мы сами туда положили (то есть мы удалим не копию, а снимок из нужной нам директории).

2. На SOF часто советуют удалять последний по дате снимок из дефолтной галереи, например, вот так:

Код: Выделить всё

public void deleteLastCapturedImage() {
    String[] projection = { 
            MediaStore.Images.ImageColumns.SIZE,
            MediaStore.Images.ImageColumns.DISPLAY_NAME,
            MediaStore.Images.ImageColumns.DATA, 
            BaseColumns._ID
    };

    Cursor c = null;
    Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

    try {
        if (u != null) {
            c = managedQuery(u, projection, null, null, null);
        }
        if ((c != null) && (c.moveToLast())) {

            ContentResolver cr = getContentResolver();
            int i = cr.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, BaseColumns._ID + "=" + c.getString(c.getColumnIndex(BaseColumns._ID)), null);

            Log.v(LOG_TAG, "Number of column deleted : " + i);

        }
    } finally {
        if (c != null) {
            c.close();
        }
    }
}
и просто выполнить этот метод в onActivityResult, когда убедимся, что нужный снимок есть в нашей директории.

Этим методом я пользоваться не советую по причине того, что очередное множество системных приложений реагирует на MediaStore.ACTION_IMAGE_CAPTURE, на удивление, так как нам надо и не создаёт в дефлтной директории копию нашего снимка. Отследить появление копии программно, в принципе, можно (проверять дату последнего файла в галерее, например), но не знаю, стоит ли на столько уродовать код.

Что же делать?

Как вариант, можно не указывать явный путь для сохранения, то есть опустить строку:

Код: Выделить всё

intent.putExtra(MediaStore.EXTRA_OUTPUT, generateFileUri());
Затем вытащить uri сохранённого файла в onActivityResult, скопировать снимок из дефолтной директории в нужную и удалить оригинал. Но бывало так, что intent.getData() и в такой ситуации показывал мне NULL. То есть, может и не работать.

Я, например, не хочу больше мучиться с нативным приложением и планирую использовать кастомную обработку камеры (уроки 132-134). Это и полезнее, и можно гораздо эффективнее фиксить баги :)

Если кто-то нашёл универсальное решение для описанной проблемы - буду рад, если поделитесь )

denis_po3
Сообщения: 14
Зарегистрирован: 01 ноя 2013, 15:45

Re: Урок 131. Камера. Используем системное приложение

Сообщение denis_po3 » 24 июн 2014, 15:22

Может, чтобы код в onActivityResult не был таким громоздким, сначала стоит сделать проверку resultCode и intent?

Код: Выделить всё

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        //super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            if (intent == null) {

                Log.d(TAG, "Intent is null");

            } else if (requestCode == REQUEST_CODE_PHOTO) {

                Bundle bundle = intent.getExtras();
                if (bundle != null) {
                    Object data = bundle.get("data");
                    if (data instanceof Bitmap) {
                        Bitmap bitmap = (Bitmap) data;
                        Log.d(TAG, "bitmap " + bitmap.getWidth() + " x "
                                + bitmap.getHeight());
                        ivPhoto.setImageBitmap(bitmap);

                    }
                }

            } else if (requestCode == REQUEST_CODE_VIDEO) {
                Log.d(TAG, "Video uri: " + intent.getData());

            }
        } else if (resultCode == RESULT_CANCELED)
            Log.d(TAG, "Result canceled");

    }
Или так будет некорректно?

По поводу системного приложения камеры в эмуляторе (API19): долго не мог заставить его работать, пока не установил внешнюю вебку вместо интегрированной в ноут. Из чего делаю вывод, что проблема была с драйверами веб-камеры.

А чтобы в ImageView вставлялась полноразмерная фотка, сохранял путь к последнему созданному изображению и отображал его.

Kotsu
Сообщения: 4
Зарегистрирован: 16 авг 2014, 12:01

Re: Урок 131. Камера. Используем системное приложение

Сообщение Kotsu » 16 авг 2014, 18:24

FireFox 31.0 падает CSS в (только)этом уроке. В хроме нормально.

Novgor
Сообщения: 17
Зарегистрирован: 07 апр 2015, 17:15

Re: Урок 131. Камера. Используем системное приложение

Сообщение Novgor » 15 май 2015, 12:09

Хочу сделать в этом приложении кнопку "Удалить". Чтобы удаляло всё что находится в ImageView. Как бы это сделать попроще?

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Урок 131. Камера. Используем системное приложение

Сообщение doter.ua » 15 май 2015, 12:14

Novgor писал(а):Хочу сделать в этом приложении кнопку "Удалить". Чтобы удаляло всё что находится в ImageView. Как бы это сделать попроще?
Обнуляй все свойства вручную.

void resetImage( ImageView iv ){
iv.set... null
...
}
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

Novgor
Сообщения: 17
Зарегистрирован: 07 апр 2015, 17:15

Re: Урок 131. Камера. Используем системное приложение

Сообщение Novgor » 15 май 2015, 12:20

Нужна инфа, как сделать, чтобы эту фотографию потом искало в интернете.

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Урок 131. Камера. Используем системное приложение

Сообщение doter.ua » 15 май 2015, 12:29

Novgor писал(а):Нужна инфа, как сделать, чтобы эту фотографию потом искало в интернете.
Google custom search api
https://developers.google.com/custom-se ... 1/overview
https://developers.google.com/apis-expl ... h.cse.list
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

Novgor
Сообщения: 17
Зарегистрирован: 07 апр 2015, 17:15

Re: Урок 131. Камера. Используем системное приложение

Сообщение Novgor » 15 май 2015, 13:16

doter.ua писал(а):
Novgor писал(а):Нужна инфа, как сделать, чтобы эту фотографию потом искало в интернете.
Google custom search api
https://developers.google.com/custom-se ... 1/overview
https://developers.google.com/apis-expl ... h.cse.list
А как мне Custom Search в приложение залепить? После создания они мне дало код в HTML.
И я толком не понял зачем мне 2 ссылка?

Аватара пользователя
doter.ua
Сообщения: 1106
Зарегистрирован: 23 ноя 2013, 16:08
Откуда: Ukraine

Re: Урок 131. Камера. Используем системное приложение

Сообщение doter.ua » 15 май 2015, 13:34

Novgor писал(а):
doter.ua писал(а):
Novgor писал(а):Нужна инфа, как сделать, чтобы эту фотографию потом искало в интернете.
Google custom search api
https://developers.google.com/custom-se ... 1/overview
https://developers.google.com/apis-expl ... h.cse.list
А как мне Custom Search в приложение залепить? После создания они мне дало код в HTML.
И я толком не понял зачем мне 2 ссылка?
Для понимания нужно немного разбираться в технологиях API. В двух словах формируется запрос(url ссылка при переходе по которой вместо html кода выдается инфа в некотором формате(JSON, XML)) с параметрами среди которых теги для поиска, различные параметры (для авторизации, проверки токенов, ид приложения у разных АПИ по разному).
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.

Trololo9831
Сообщения: 1
Зарегистрирован: 07 сен 2018, 10:30

Re: Урок 131. Камера. Используем системное приложение

Сообщение Trololo9831 » 07 сен 2018, 10:31

На эмуляторе сразу высыпались ошибки. Камера отсутствует!
Решил испытать на устройстве. Снимок делает но в приложении фото не показывает. Фото сохраняет не по пути приложения а в то место куда обычно сохраняет камера! Андроид 5.0.2
Может кто что посоветует!

Ответить