Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Rembo88
0 / 0 / 0
Регистрация: 05.10.2013
Сообщений: 39
#1

Не удаётся проинициализировать камеру - Программирование Android

05.06.2015, 12:43. Просмотров 621. Ответов 5
Метки нет (Все метки)

Коллеги,пытаясь создать кастомную камеру столкнулся со следующей проблемой:
при попытке получить доступ к камере в методе
Java
1
camera = Camera.open(CAMERA_ID);
выбрасывается исключение java.lang.RuntimeException: Fail to connect to camera service, таким образом объект camera принимает значение null и в дальнейшем с ним нельзя работать.
Результат гугления говорит только о том, что в AndroidManifest должны быть указаны соответствующие для камеры разрешения:
XML
1
2
3
4
5
    
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
Все эти разрешения у меня есть, экспериментировал с ними, но проблему это не решило.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
Ниже приведён полный код моего класса с камерой.Может быть кто-то подскажет в чём я накосячил?
 
public class CustomCamera extends Activity {
 
    /** Виджет для предпросмотра фотографий */
    SurfaceView sv;
    /** Адаптер для SurfaceView */
    SurfaceHolder holder;
    /** Объект для получения информации об изменениях в surface */
    HolderCallback holderCallback;
    /** Объект для доступа к камере */
    static Camera camera = null;
    /** Наличие камеры */
    private boolean hasCamera = false;
    Button shotButton;
 
    final int CAMERA_ID = 0;
    final boolean FULL_SCREEN = true;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
 
        // Без заголовка
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // Полноэкранный режим
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // Устанавливаю разметку
        setContentView(R.layout.custom_camera_activity2);
 
        shotButton = (Button) findViewById(R.id.btnTakePicture);
        shotButton.setOnClickListener(new View.OnClickListener() {
            // Отправляем изображение при нажатии на кнопку сфотографировать
            @Override
            public void onClick(View v) {
                if (hasCamera) {
                    camera.takePicture(null, null, new Camera.PictureCallback() {
                        @Override
                        public void onPictureTaken(byte[] data, Camera camera) {
                            try {
                                Intent intent = new Intent();
                                intent.putExtra("data", data);
                                setResult(RESULT_OK, intent);
                                finish();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        });
 
        // Инициализирую виджет для предпросмотра
        sv = (SurfaceView) findViewById(R.id.surfaceView);
        // Получаю адаптер для виджета предпросмотра
        holder = sv.getHolder();
        // Устанавливаю тип адаптера
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 
        holderCallback = new HolderCallback();
 
        // Узнаём количество камер
        int numCameras = Camera.getNumberOfCameras();
        if (numCameras > 0) {
            hasCamera = true;
        }
 
        holder.addCallback(holderCallback);
    }
 
    // Обработка повторного включения камеры
    @Override
    protected void onResume() {
 
        super.onResume();
        // Если есть камера
        if (hasCamera) {
            // Получаем доступ к камере
            try {
                camera = Camera.open(CAMERA_ID);
                // Настраиваем размер surface
                setPreviewSize(FULL_SCREEN);
            } catch (Exception e) {
                e.printStackTrace();
                Log.d(Constant.DEBUG_TAG, "Не удалось получить доступ к камере");
            }
        } else {
            Toast.makeText(this, "В устройстве отсутствует камера", Toast.LENGTH_SHORT).show();
            Log.d(Constant.DEBUG_TAG, "В устройстве отсутствует камера");
        }
    }
 
    // Обработка выключения камеры
    @Override
    protected void onPause() {
 
        super.onPause();
        if (camera != null) {
            // Останавливаем предпросмотр
            camera.stopPreview();
            // Освобождаем камеру для использования другими приложениями
            camera.release();
        }
        camera = null;
    }
 
    class HolderCallback implements SurfaceHolder.Callback {
 
        // Начало трансляции изображения
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
 
            try {
                // Подключаем камеру к адаптеру предпросмотра
                camera.setPreviewDisplay(holder);
                // Запускаем камеру
                camera.startPreview();
            } catch (NullPointerException npe) {
                npe.printStackTrace();
                Log.d(Constant.DEBUG_TAG, "Объект camera не проинициализирован в методе onResume");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
 
        // Был изменен формат или размер surface
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
 
            try {
            // Останавливаем камеру
            camera.stopPreview();
            // Настраиваем камеру с учетом поворота устройства
            setCameraDisplayOrientation(CAMERA_ID);
                // Подключаем камеру к адаптеру предпросмотра
                camera.setPreviewDisplay(holder);
                // Запускаем камеру
                camera.startPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 
        // surface более недоступен
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    }
 
    // Определяем размеры surface с учетом экрана и изображения с камеры
    void setPreviewSize(boolean fullScreen) {
 
        // Получаем размеры экрана
        Display display = getWindowManager().getDefaultDisplay();
        boolean widthIsMax = display.getWidth() > display.getHeight();
 
        // Определяем размеры превью камеры
        Size size = camera.getParameters().getPreviewSize();
 
        RectF rectDisplay = new RectF();
        RectF rectPreview = new RectF();
 
        // RectF экрана, соотвествует размерам экрана
        rectDisplay.set(0, 0, display.getWidth(), display.getHeight());
 
        // RectF первью
        if (widthIsMax) {
            // Превью в горизонтальной ориентации
            rectPreview.set(0, 0, size.width, size.height);
        } else {
            // Превью в вертикальной ориентации
            rectPreview.set(0, 0, size.height, size.width);
        }
 
        Matrix matrix = new Matrix();
        // Подготовка матрицы преобразования
        if (!fullScreen) {
            // Если превью будет "втиснут" в экран (второй вариант из урока)
            matrix.setRectToRect(rectPreview, rectDisplay,
                    Matrix.ScaleToFit.START);
        } else {
            // если экран будет "втиснут" в превью (третий вариант из урока)
            matrix.setRectToRect(rectDisplay, rectPreview,
                    Matrix.ScaleToFit.START);
            matrix.invert(matrix);
        }
        // преобразование
        matrix.mapRect(rectPreview);
 
        // установка размеров surface из получившегося преобразования
        sv.getLayoutParams().height = (int) (rectPreview.bottom);
        sv.getLayoutParams().width = (int) (rectPreview.right);
    }
 
    // Устанавливаем ориентацию предпросмотра
    void setCameraDisplayOrientation(int cameraId) {
        // определяем насколько повернут экран от нормального положения
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }
 
        int result = 0;
 
        // Получаем инфо по камере cameraId
        CameraInfo info = new CameraInfo();
        Camera.getCameraInfo(cameraId, info);
 
        // Задняя камера
        if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
            result = ((360 - degrees) + info.orientation);
        } else
            // передняя камера
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                result = ((360 - degrees) - info.orientation);
                result += 360;
            }
        result = result % 360;
        camera.setDisplayOrientation(result);
    }
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2015, 12:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не удаётся проинициализировать камеру (Программирование Android):

Запустить камеру в приложении - Программирование Android
Нужно в приложении запустить камеру. Нашел примеры: Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); но проблема...

Можно ли заменить камеру по умолчанию на другое приложение? - Программирование Android
Всем привет! Ситуация такая: Есть гибридное приложение, к коду которого у меня нет доступа, но могу писать страницы. использую...

Не удаётся создать проект в Эклипсе - Программирование Android
Не получается создать андроид в Эклипсе. При попытке создания выдаёт ошибку &quot;Errors occurred during the build. Errors running builder...

Не удаётся подключить пространство имён android.nfc - Программирование Android
Доброго времени суток. Пишу в android studio. Пытаюсь подключить пространство имён android.nfc. import android.nfc; Получаю ошибку ...

Не могу проинициализировать HDD - Жесткие диски
Здравствуйте! На днях случайно уронил подключенный WD Elements 1024. Он был вставлен, и во время падения его выдернуло... При...

проинициализировать строку в конструкторе - C++
Привет. Помогите, пожалуйста разобраться со строками. что с ними делать в конструкторе, функции, деструкторе. #include &quot;stdafx.h&quot; ...

5
CoolMind
419 / 402 / 65
Регистрация: 06.10.2012
Сообщений: 1,727
05.06.2015, 16:31 #2
Rembo88, коллега, подозреваю, мы с вами решаем одно и то же задание)
И у меня такая же ерунда.

Добавлено через 8 минут
Кстати, на другом устройстве заработало сразу.
0
Pablito
2477 / 1961 / 611
Регистрация: 12.05.2014
Сообщений: 6,866
Завершенные тесты: 1
05.06.2015, 16:55 #3
я уже писал в соседней теме - попробуйте перезагрузить устройство
если не поможет то Camera.open(); без параметра, но сначала перезагрузка
0
Rembo88
0 / 0 / 0
Регистрация: 05.10.2013
Сообщений: 39
05.06.2015, 17:32  [ТС] #4
Пробовал запускать с
Java
1
Camera.open();
, а также явно указывать
Java
1
Camera.open(0);
и
Java
1
Camera.open(1);
,но это не помогло,перезагрузка также не помогла.
0
Pablito
2477 / 1961 / 611
Регистрация: 12.05.2014
Сообщений: 6,866
Завершенные тесты: 1
05.06.2015, 17:59 #5
ради интереса скопировал строчки из первого сообщения в манифест
и в onCreate написал Camera c = Camera.open();
все прошло на ура
проверил на первом попавшемся девайсе в Genymotion

понимаю что вопрос глупый, но пермишены точно в правильное место вставлены в манифест?
0
CoolMind
419 / 402 / 65
Регистрация: 06.10.2012
Сообщений: 1,727
05.06.2015, 20:06 #6
Паблито, у меня та же тема. Проверял на Android 5 - всё работает. Взял устройство с Android 2.3.3, перезагружал - не работает. Вот так ещё бывает.

Добавлено через 1 час 14 минут
Короче, тема такая. По многочисленным сообщениям с SO камера некорректно работает в портретном режиме. Запустил в пейзажном - заработало.

Добавлено через 45 минут
Ну это уже смешно. Запускаешь в пейзажном, крутишь устройство - всё работает, пока не станет в портретном. Дальше изображение подвисает. Затем снова работает, когда крутишь дальше. Когда устройство становится "вверх ногами", изображение может неожиданно перевернуться зеркально.

Добавлено через 56 секунд
Не зря задание состоит в поиске багов. Авторы топиков на SO и не знали, сколько их можно словить.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.06.2015, 20:06
Привет! Вот еще темы с ответами:

Проинициализировать массив случайными символами от A до Z - C++
Здравствуйте!Я не могу понять,что тут не так..помогите разобраться! Задача: типа char размером в 4х11х3 элементов. Проинициализировать...

Проинициализировать массив во время компиляции - C++
Проблема с распаковкой параметр-пака.#include &lt;utility&gt; constexpr unsigned long long fact(int n) { unsigned long long res = 1;...

Проинициализировать массив случайными символами от A до Z. - C++
Проинициализировать массив случайными символами от A до Z. Как это можно сделать?

Как правильно проинициализировать массив вручную? - C++
Здрасти. как правильно проинициализировать массив в ручную? а то у меня ошибка main.cpp|60|error: expected primary-expression before '{'...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Yandex
Объявления
05.06.2015, 20:06
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru