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

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

Восстановить пароль Регистрация
 
Rembo88
0 / 0 / 0
Регистрация: 05.10.2013
Сообщений: 39
05.06.2015, 12:43     Не удаётся проинициализировать камеру #1
Коллеги,пытаясь создать кастомную камеру столкнулся со следующей проблемой:
при попытке получить доступ к камере в методе
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);
    }
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2015, 12:43     Не удаётся проинициализировать камеру
Посмотрите здесь:

Как правильно проинициализировать массив вручную? C++
Проинициализировать массив случайными символами от A до Z. C++
Проинициализировать массив случайными символами от A до Z C++
проинициализировать строку в конструкторе C++
C++ Как повторно проинициализировать переменную конструктором?
Можно ли заменить камеру по умолчанию на другое приложение? Android
C++ Как проинициализировать весь массив объектов?
Android Запустить камеру в приложении
C++ Как проинициализировать static поле класса?
Не могу проинициализировать HDD
Не удаётся создать проект в Эклипсе Android
Android Не удаётся подключить пространство имён android.nfc

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
CoolMind
411 / 394 / 65
Регистрация: 06.10.2012
Сообщений: 1,701
05.06.2015, 16:31     Не удаётся проинициализировать камеру #2
Rembo88, коллега, подозреваю, мы с вами решаем одно и то же задание)
И у меня такая же ерунда.

Добавлено через 8 минут
Кстати, на другом устройстве заработало сразу.
Паблито
не спать!
1868 / 1602 / 493
Регистрация: 12.05.2014
Сообщений: 5,796
Завершенные тесты: 1
05.06.2015, 16:55     Не удаётся проинициализировать камеру #3
я уже писал в соседней теме - попробуйте перезагрузить устройство
если не поможет то Camera.open(); без параметра, но сначала перезагрузка
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);
,но это не помогло,перезагрузка также не помогла.
Паблито
не спать!
1868 / 1602 / 493
Регистрация: 12.05.2014
Сообщений: 5,796
Завершенные тесты: 1
05.06.2015, 17:59     Не удаётся проинициализировать камеру #5
ради интереса скопировал строчки из первого сообщения в манифест
и в onCreate написал Camera c = Camera.open();
все прошло на ура
проверил на первом попавшемся девайсе в Genymotion

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

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

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

Добавлено через 56 секунд
Не зря задание состоит в поиске багов. Авторы топиков на SO и не знали, сколько их можно словить.
Yandex
Объявления
05.06.2015, 20:06     Не удаётся проинициализировать камеру
Ответ Создать тему
Опции темы

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