android - intent - RuntimeException en Camera.setParameters() en nexus one
intent camera android (7)
Copié el código de la respuesta aquí y todavía obtengo una excepción RuntimeException: setParameters falló en mi nexo. Mi archivo de manifiesto tiene permisos de cámara y de activación del bloqueo. Esto funciona en el emulador, y en el droide no recibo el error pero tiene un problema de rotación.
Algunos proyectos de cámara de código abierto como opencamera siempre usan try-catch
para llamar a Camera.setParameters:
private void setCameraParameters(Camera.Parameters parameters) {
if( MyDebug.LOG )
Log.d(TAG, "setCameraParameters");
try {
camera.setParameters(parameters);
if( MyDebug.LOG )
Log.d(TAG, "done");
} catch (RuntimeException e) {
// just in case something has gone wrong
if( MyDebug.LOG )
Log.d(TAG, "failed to set parameters");
e.printStackTrace();
count_camera_parameters_exception++;
}
}
Además, siempre obtenga los últimos getParameters
antes de llamar a setParameters
esta manera:
void setRotation(int rotation) {
Camera.Parameters parameters = this.getParameters();
parameters.setRotation(rotation);
setCameraParameters(parameters);
}
Corrigí esto haciendo lo que Roman dijo, con el código:
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
Camera.Size cs = sizes.get(0);
parameters.setPreviewSize(cs.width, cs.height);
camera.setParameters(parameters);
La solución de Sam es correcta, pero la imagen de salida aún se amplía un poco en varios dispositivos de tableta. Una de las mejores prácticas que encontré en Internet, deberíamos establecer en el host de la cámara para que las propiedades se reutilicen cada vez que se reanude la cámara. Aquí se implementa el método en CameraHost:
@Override
public Parameters adjustPreviewParameters(Parameters parameters) {
List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
Camera.Size cs = sizes.get(0);
parameters.setPreviewSize(cs.width, cs.height);
return super.adjustPreviewParameters(parameters);
}
Nada de lo anterior resolvió esto por mí. Sin embargo, agregar este código antes de establecer los parámetros lo hizo.
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
//now set your parameters
Para mí, esto sucedería después de tomar una foto y la vista previa se congelaría, hasta que actualice mi llamada para que los parámetros sean los siguientes. Siempre es importante con este error asegurarse de verificar todos los parámetros que la cámara solicita establecer para asegurarse de que todos los parámetros a los que solicita que se establezca la cámara sean posibles para la cámara.
Camera.Parameters parameters = myCamera.getParameters();
Con el tamaño de vista previa:
if (myCamera.getParameters().getSupportedPreviewSizes() != null){
Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);;
parameters.setPreviewSize(previewSize.width, previewSize.height);
}
Con los modos de flash / enfoque:
if(parameters.getSupportedFocusModes() != null && parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
if (parameters.getSupportedFlashModes() != null && parameters.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_AUTO)){
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
}
myCamera.setParameters(parameters);
Todo esto envuelto en un bonito intento {} catch () {} funciona muy bien. Buena suerte.
Aquí está el tamaño de la vista previa de getOptimal de este gran tutorial :
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height)
{
// Source: http://.com/questions/7942378/android-camera-will-not-work-startpreview-fails
Camera.Size optimalSize = null;
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) height / width;
// Try to find a size match which suits the whole screen minus the menu on the left.
for (Camera.Size size : sizes){
if (size.height != width) continue;
double ratio = (double) size.width / size.height;
if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){
optimalSize = size;
}
}
// If we cannot find the one that matches the aspect ratio, ignore the requirement.
if (optimalSize == null) {
// TODO : Backup in case we don''t get a size.
}
return optimalSize;
}
Por lo que vale la pena, la fuente de mi problema terminó siendo que estaba tratando de llamar a parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
sin verificar primero que los modos de flash eran compatibles al verificar que parameters.getFlashMode() != null
.
Hay más de una causa para esta excepción mal documentada, así que verifique todos sus parámetros y no solo que esté usando un supportedPreviewSize
.
Es muy probable que estés solicitando un tamaño de vista previa no válido. Si verifica los resultados de adb logcat
, probablemente verá algo como esto:
E/QualcommCameraHardware(22732): Invalid preview size requested: 480x724
La solución es solicitar el tamaño de vista previa disponible más cercano al que desea; puede obtener una lista de tamaños de vista previa disponibles llamando a getSupportedPreviewSizes
en el objeto Camera.Parameters devuelto por Camera.getParameters .