Android调用camera错误setParameters failed深层解析

仰天大笑出门去,我辈岂是蓬蒿人。这篇文章主要讲述Android调用camera错误setParameters failed深层解析相关的知识,希望能为你提供帮助。
1. CameraCamera是android framework里面支持的,同意你拍照和拍摄视频的设备,那么,在使用camera开发中总是会遇到一些问题,比例如以下面这样子的:
E/AndroidRuntime(1542): java.lang.RuntimeException: setParameters failed
E/AndroidRuntime(1542):   at android.hardware.Camera.native_setParameters(Native Method)
E/AndroidRuntime(1542):   at android.hardware.Camera.setParameters(Camera.java:914)
出现这样的错误。依据错误提示我们能够知道是android的setParameters方法出错了。
2、那该怎样解决呢?我们知道camera的parameters中也有非常多參数设置的,是哪个出错了呢?非常多人不知所以然就上网開始找,找不到就開始各种推測,一个个參数设置过去,事实上最有效的方式是究竟层找原因。ok,让我们打开android代码找到camera类。然后查找setParameters方法。

private native final void native_setParameters(String params); /** * Changes the settings for this Camera service. * * @param params the Parameters to use for this Camera service * @throws RuntimeException if any parameter is invalid or not supported. * @see #getParameters() */ public void setParameters(Parameters params) { native_setParameters(params.flatten()); }


从这段代码中代码中。我们能够得到什么信息呢,setParameters方法是调用jni方法native_setParameters的方法,事实上看到这里就差并不多了,由于再去查看jni方法是非常麻烦的。毕竟我们日常开发使用大部分是java代码。我们能够发现传输进来的是Parameters參数,调用了Parameters的flatten方法。
我们查找flatten的代码进行查看。



/** * Creates a single string with all the parameters set in * this Parameters object. * < p> The {@link #unflatten(String)} method does the reverse.< /p> * * @return a String with all values from this Parameters object, in *semi-colon delimited key-value pairs */ public String flatten() { StringBuilder flattened = new StringBuilder(); for (String k : mMap.keySet()) { flattened.append(k); flattened.append("="); flattened.append(mMap.get(k)); flattened.append("; "); } // chop off the extra semicolon at the end flattened.deleteCharAt(flattened.length()-1); return flattened.toString(); }


从这段代码中,我们又能得到什么信息呢。我们能够看到提供数据的时候,数据都是从mMap中获取的。ok,接下来,我们查看一下mMap是有几个方法对其进行了赋值呢。

/** * Takes a flattened string of parameters and adds each one to * this Parameters object. * < p> The {@link #flatten()} method does the reverse.< /p> * * @param flattened a String of parameters (key-value paired) that *are semi-colon delimited */ public void unflatten(String flattened) { mMap.clear(); StringTokenizer tokenizer = new StringTokenizer(flattened, "; "); while (tokenizer.hasMoreElements()) { String kv = tokenizer.nextToken(); int pos = kv.indexOf(‘=‘); if (pos == -1) { continue; } String k = kv.substring(0, pos); String v = kv.substring(pos + 1); mMap.put(k, v); } }/** * Sets a String parameter. * * @param keythe key name for the parameter * @param value the String value of the parameter */ public void set(String key, String value) { if (key.indexOf(‘=‘) != -1 || key.indexOf(‘; ‘) != -1) { Log.e(TAG, "Key \"" + key + "\" contains invalid character (= or ; )"); return; } if (value.indexOf(‘=‘) != -1 || value.indexOf(‘; ‘) != -1) { Log.e(TAG, "Value \"" + value + "\" contains invalid character (= or ; )"); return; }mMap.put(key, value); }/** * Sets an integer parameter. * * @param keythe key name for the parameter * @param value the int value of the parameter */ public void set(String key, int value) { mMap.put(key, Integer.toString(value)); }private void set(String key, List< Area> areas) { if (areas == null) { set(key, "(0,0,0,0,0)"); } else { StringBuilder buffer = new StringBuilder(); for (int i = 0; i < areas.size(); i++) { Area area = areas.get(i); Rect rect = area.rect; buffer.append(‘(‘); buffer.append(rect.left); buffer.append(‘,‘); buffer.append(rect.top); buffer.append(‘,‘); buffer.append(rect.right); buffer.append(‘,‘); buffer.append(rect.bottom); buffer.append(‘,‘); buffer.append(area.weight); buffer.append(‘)‘); if (i != areas.size() - 1) buffer.append(‘,‘); } set(key, buffer.toString()); } }/** * Returns the value of a String parameter. * * @param key the key name for the parameter * @return the String value of the parameter */ public String get(String key) { return mMap.get(key); }/** * Sets the dimensions for preview pictures. If the preview has already * started, applications should stop the preview first before changing * preview size. * * The sides of width and height are based on camera orientation. That * is, the preview size is the size before it is rotated by display * orientation. So applications need to consider the display orientation * while setting preview size. For example, suppose the camera supports * both 480x320 and 320x480 preview sizes. The application wants a 3:2 * preview ratio. If the display orientation is set to 0 or 180, preview * size should be set to 480x320. If the display orientation is set to * 90 or 270, preview size should be set to 320x480. The display * orientation should also be considered while setting picture size and * thumbnail size. * * @param widththe width of the pictures, in pixels * @param height the height of the pictures, in pixels * @see #setDisplayOrientation(int) * @see #getCameraInfo(int, CameraInfo) * @see #setPictureSize(int, int) * @see #setJpegThumbnailSize(int, int) */ public void setPreviewSize(int width, int height) { String v = Integer.toString(width) + "x" + Integer.toString(height); set(KEY_PREVIEW_SIZE, v); }



/** * < p> Sets the dimensions for EXIF thumbnail in Jpeg picture. If * applications set both width and height to 0, EXIF will not contain * thumbnail.< /p> * * < p> Applications need to consider the display orientation. See {@link * #setPreviewSize(int,int)} for reference.< /p> * * @param widththe width of the thumbnail, in pixels * @param height the height of the thumbnail, in pixels * @see #setPreviewSize(int,int) */ public void setJpegThumbnailSize(int width, int height) { set(KEY_JPEG_THUMBNAIL_WIDTH, width); set(KEY_JPEG_THUMBNAIL_HEIGHT, height); }/** * Sets the quality of the EXIF thumbnail in Jpeg picture. * * @param quality the JPEG quality of the EXIF thumbnail. The range is 1 *to 100, with 100 being the best. */ public void setJpegThumbnailQuality(int quality) { set(KEY_JPEG_THUMBNAIL_QUALITY, quality); }/** * Sets Jpeg quality of captured picture. * * @param quality the JPEG quality of captured picture. The range is 1 *to 100, with 100 being the best. */ public void setJpegQuality(int quality) { set(KEY_JPEG_QUALITY, quality); }/** * Sets the rate at which preview frames are received. This is the * target frame rate. The actual frame rate depends on the driver. * * @param fps the frame rate (frames per second) * @deprecated replaced by {@link #setPreviewFpsRange(int,int)} */ @Deprecated public void setPreviewFrameRate(int fps) { set(KEY_PREVIEW_FRAME_RATE, fps); }/** * Sets the maximum and maximum preview fps. This controls the rate of * preview frames received in {@link PreviewCallback}. The minimum and * maximum preview fps must be one of the elements from {@link * #getSupportedPreviewFpsRange}. * * @param min the minimum preview fps (scaled by 1000). * @param max the maximum preview fps (scaled by 1000). * @throws RuntimeException if fps range is invalid. * @see #setPreviewCallbackWithBuffer(Camera.PreviewCallback) * @see #getSupportedPreviewFpsRange() */ public void setPreviewFpsRange(int min, int max) { set(KEY_PREVIEW_FPS_RANGE, "" + min + "," + max); }/** * Sets the image format for preview pictures. * < p> If this is never called, the default format will be * {@link android.graphics.ImageFormat#NV21}, which * uses the NV21 encoding format.< /p> * * @param pixel_format the desired preview picture format, defined *by one of the {@link android.graphics.ImageFormat} constants. *(E.g., < var> ImageFormat.NV21< /var> (default), *< var> ImageFormat.RGB_565< /var> , or *< var> ImageFormat.JPEG< /var> ) * @see android.graphics.ImageFormat */ public void setPreviewFormat(int pixel_format) { String s = cameraFormatForPixelFormat(pixel_format); if (s == null) { throw new IllegalArgumentException( "Invalid pixel_format=" + pixel_format); }set(KEY_PREVIEW_FORMAT, s); }/** * < p> Sets the dimensions for pictures.< /p> * * < p> Applications need to consider the display orientation. See {@link * #setPreviewSize(int,int)} for reference.< /p> * * @param widththe width for pictures, in pixels * @param height the height for pictures, in pixels * @see #setPreviewSize(int,int) * */ public void setPictureSize(int width, int height) { String v = Integer.toString(width) + "x" + Integer.toString(height); set(KEY_PICTURE_SIZE, v); }/** * Sets the image format for pictures. * * @param pixel_format the desired picture format *(< var> ImageFormat.NV21< /var> , *< var> ImageFormat.RGB_565< /var> , or *< var> ImageFormat.JPEG< /var> ) * @see android.graphics.ImageFormat */ public void setPictureFormat(int pixel_format) { String s = cameraFormatForPixelFormat(pixel_format); if (s == null) { throw new IllegalArgumentException( "Invalid pixel_format=" + pixel_format); }set(KEY_PICTURE_FORMAT, s); }




ok,错误的地方。我们就定位在这么几个地方了。在自己写的代码里面,查看一下是否调用了这几个方法~~~。android源代码还是凝视得比較清晰的,看看方法英文说明,看是否參数有出现了错误。
当时我的是使用setPictureSize时出现了错误,依据方法说明,我简单解释下。为什么会出错。由于parameters.setPictureSize(320, 480)(设置分辨率)的參数有误,假设不清楚分辨率能够却掉这句话。再执行就OK了。
 
注:最后找了一下原因,感觉非常easy,在实际 开发中。有时候一个小问题。就让人忙乎一个下午也是正常滴。




【Android调用camera错误setParameters failed深层解析】













    推荐阅读