Android調用camera錯誤setParameters failed深層解析

來源:互聯網
上載者:User

標籤:mini   parameter   time   extra   get   tpi   tca   post   indexof   

1. Camera

Camera是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 key   the 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 key   the 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 width  the 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 width  the 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 width  the 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深層解析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.