Java tutorial
/* * Copyright 2013 wada811<at.wada811@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package at.wada811.utils; import android.annotation.TargetApi; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.pm.PackageManager; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.Size; import android.media.CamcorderProfile; import android.os.Build; import at.wada811.android.library.R; import org.json.JSONException; import org.json.JSONObject; import java.util.List; public class CameraUtils { private static final boolean DEBUG = false; /** * ????? * * @param context * @return */ public static boolean hasFeatureCamera(Context context) { boolean hasCamera = false; if (PreferenceUtils.contains(context, PackageManager.FEATURE_CAMERA)) { hasCamera = PreferenceUtils.getBoolean(context, PackageManager.FEATURE_CAMERA, hasCamera); } else { PackageManager packageManager = context.getApplicationContext().getPackageManager(); hasCamera = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA); PreferenceUtils.putBoolean(context, PackageManager.FEATURE_CAMERA, hasCamera); } return hasCamera; } @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public static boolean isCameraDisabled(Context context) { if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.ICE_CREAM_SANDWICH)) { DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context .getSystemService(Context.DEVICE_POLICY_SERVICE); return devicePolicyManager.getCameraDisabled(null); } else { return false; } } /** * ????? * * @param context * @return */ public static boolean hasFeatureAutoFocus(Context context) { boolean hasAutoFocus = false; if (PreferenceUtils.contains(context, PackageManager.FEATURE_CAMERA_AUTOFOCUS)) { hasAutoFocus = PreferenceUtils.getBoolean(context, PackageManager.FEATURE_CAMERA_AUTOFOCUS, hasAutoFocus); } else { PackageManager packageManager = context.getApplicationContext().getPackageManager(); hasAutoFocus = packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_AUTOFOCUS); PreferenceUtils.putBoolean(context, PackageManager.FEATURE_CAMERA_AUTOFOCUS, hasAutoFocus); } return hasAutoFocus; } /** * ?? * * @param nCameraId * @return */ public static CameraInfo getCameraInfo(int nCameraId) { Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(nCameraId, info); return info; } /** * ?????? * * @param info * @return */ public static boolean isBackCamera(CameraInfo info) { return info.facing == CameraInfo.CAMERA_FACING_BACK; } /** * ?????? * * @param activity * @param nCameraId * @return displayOrientation */ public static int getCameraDisplayOrientation(Context context, CameraInfo info) { if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.GINGERBREAD)) { int degrees = DisplayUtils.getRotationDegrees(context); if (DEBUG) { LogUtils.v("degrees: " + degrees); } int displayOrientation; if (CameraUtils.isBackCamera(info)) { // if (DEBUG) { LogUtils.v(String.valueOf(degrees)); } if (DEBUG) { LogUtils.v(String.valueOf(info.orientation)); } displayOrientation = (360 - degrees + info.orientation) % 360; if (DEBUG) { LogUtils.v(String.valueOf(displayOrientation)); } displayOrientation = (360 + displayOrientation) % 360; if (DEBUG) { LogUtils.v(String.valueOf(displayOrientation)); } } else { // if (DEBUG) { LogUtils.v(String.valueOf(degrees)); } if (DEBUG) { LogUtils.v(String.valueOf(info.orientation)); } displayOrientation = (360 - degrees - info.orientation) % 360; if (DEBUG) { LogUtils.v(String.valueOf(displayOrientation)); } displayOrientation = (360 + displayOrientation) % 360; if (DEBUG) { LogUtils.v(String.valueOf(displayOrientation)); } } return displayOrientation; } return 90; } /** * ??????? * * @param cameraId * @param displayOrientation * @return pictureOrientaion */ public static int getPictureOrientaion(CameraInfo info, int displayOrientation) { int pictureOrientaion; if (CameraUtils.isBackCamera(info)) { pictureOrientaion = displayOrientation; } else { pictureOrientaion = (360 - displayOrientation) % 360; } return pictureOrientaion; } public static Size getPictureSize(Context context, Camera camera) { final List<Size> sizes = camera.getParameters().getSupportedPictureSizes(); final double ASPECT_TOLERANCE = 0.07; final boolean isPortrait = DisplayUtils.isPortrait(context); final int width = DisplayUtils.getWidth(context); final int height = DisplayUtils.getHeight(context); if (DEBUG) { LogUtils.v("width: " + width); } if (DEBUG) { LogUtils.v("height: " + height); } final double targetRatio = isPortrait ? (double) height / width : (double) width / height; final int targetHeight = isPortrait ? width : height; Size optimalSize = null; double minDiff = Double.MAX_VALUE; if (DEBUG) { LogUtils.v("targetRatio: " + targetRatio); } for (Size size : sizes) { double pictureRatio = isPortrait ? (double) size.height / size.width : (double) size.width / size.height; pictureRatio = (double) size.width / size.height; if (DEBUG) { LogUtils.v("size.width: " + size.width); } if (DEBUG) { LogUtils.v("size.height: " + size.height); } if (DEBUG) { LogUtils.v("pictureRatio: " + pictureRatio); } if (Math.abs(pictureRatio - targetRatio) > ASPECT_TOLERANCE) { continue; } if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } if (DEBUG) { LogUtils.v("optimalSize.width: " + optimalSize.width); } if (DEBUG) { LogUtils.v("optimalSize.height: " + optimalSize.height); } return optimalSize; } /** * ? * * @param camera * @param pictureSize */ public static void setPictureSize(Camera camera, Size pictureSize) { Parameters params = camera.getParameters(); params.setPictureSize(pictureSize.width, pictureSize.height); camera.setParameters(params); } /** * Returns the best preview size * * @param context * @param camera */ public static Size getOptimalPreviewSize(Context context, Camera camera) { final List<Size> sizes = camera.getParameters().getSupportedPreviewSizes(); final double ASPECT_TOLERANCE = 0.07; final boolean isPortrait = DisplayUtils.isPortrait(context); final Size pictureSize = camera.getParameters().getPictureSize(); final int width = pictureSize.width; final int height = pictureSize.height; if (DEBUG) { LogUtils.v("width: " + width); } if (DEBUG) { LogUtils.v("height: " + height); } final double targetRatio = isPortrait ? (double) height / width : (double) width / height; final int targetHeight = isPortrait ? width : height; Size optimalSize = null; double minDiff = Double.MAX_VALUE; if (DEBUG) { LogUtils.v("targetRatio: " + targetRatio); } for (Size size : sizes) { double previewRatio = isPortrait ? (double) size.height / size.width : (double) size.width / size.height; previewRatio = (double) size.width / size.height; if (DEBUG) { LogUtils.v("size.width: " + size.width); } if (DEBUG) { LogUtils.v("size.height: " + size.height); } if (DEBUG) { LogUtils.v("previewRatio: " + previewRatio); } if (Math.abs(previewRatio - targetRatio) > ASPECT_TOLERANCE) { continue; } if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } if (optimalSize == null) { minDiff = Double.MAX_VALUE; for (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } if (DEBUG) { LogUtils.v("optimalSize.width: " + optimalSize.width); } if (DEBUG) { LogUtils.v("optimalSize.height: " + optimalSize.height); } return optimalSize; } /** * ??? * * @param camera * @param previewSize */ public static void setPreviewSize(Camera camera, Size previewSize) { Parameters params = camera.getParameters(); params.setPreviewSize(previewSize.width, previewSize.height); camera.setParameters(params); } /** * ???????? * * @param context * @param camera * @return scaledPreviewSize */ public static Size getScaledPreviewSize(Context context, Camera camera) { Size previewSize = camera.getParameters().getPreviewSize(); boolean isPortrait = DisplayUtils.isPortrait(context); final int displayWidth = DisplayUtils.getWidth(context); final int displayHeight = DisplayUtils.getHeight(context); if (DEBUG) { LogUtils.v("displayWidth: " + displayWidth); } if (DEBUG) { LogUtils.v("displayHeight: " + displayHeight); } PreferenceUtils.putInt(context, context.getString(R.string.keyDisplayWidth), displayWidth); PreferenceUtils.putInt(context, context.getString(R.string.keyDisplayHeight), displayHeight); final int previewWidth = isPortrait ? previewSize.height : previewSize.width; final int previewHeight = isPortrait ? previewSize.width : previewSize.height; if (DEBUG) { LogUtils.v("previewWidth: " + previewWidth); } if (DEBUG) { LogUtils.v("previewHeight: " + previewHeight); } PreferenceUtils.putInt(context, context.getString(R.string.keyPreviewWidth), previewWidth); PreferenceUtils.putInt(context, context.getString(R.string.keyPreviewHeight), previewHeight); double displayRatio = displayHeight > displayWidth ? (double) displayHeight / displayWidth : (double) displayWidth / displayHeight; double previewRatio = previewHeight > previewWidth ? (double) previewHeight / previewWidth : (double) previewWidth / previewHeight; if (DEBUG) { LogUtils.v("displayRatio: " + displayRatio); } if (DEBUG) { LogUtils.v("previewRatio: " + previewRatio); } PreferenceUtils.putFloat(context, context.getString(R.string.keyDisplayRatio), (float) displayRatio); PreferenceUtils.putFloat(context, context.getString(R.string.keyPreviewRatio), (float) previewRatio); int scaledChildWidth = displayWidth; int scaledChildHeight = displayHeight; if (displayRatio <= previewRatio) { if (isPortrait) { if (DEBUG) { LogUtils.v("Portrait"); } scaledChildWidth = (displayHeight * previewWidth) / previewHeight; scaledChildHeight = (scaledChildWidth * previewHeight) / previewWidth; } else { if (DEBUG) { LogUtils.v("Landscape"); } scaledChildHeight = (displayWidth * previewHeight) / previewWidth; scaledChildWidth = (scaledChildHeight * previewWidth) / previewHeight; } } else { if (isPortrait) { if (DEBUG) { LogUtils.v("Portrait"); } scaledChildHeight = (displayWidth * previewHeight) / previewWidth; scaledChildWidth = (scaledChildHeight * previewWidth) / previewHeight; } else { if (DEBUG) { LogUtils.v("Landscape"); } scaledChildWidth = (displayHeight * previewWidth) / previewHeight; scaledChildHeight = (scaledChildWidth * previewHeight) / previewWidth; } } if (DEBUG) { LogUtils.v("scaledChildWidth: " + scaledChildWidth); } if (DEBUG) { LogUtils.v("scaledChildHeight: " + scaledChildHeight); } PreferenceUtils.putInt(context, context.getString(R.string.keyScaledChildWidth), scaledChildWidth); PreferenceUtils.putInt(context, context.getString(R.string.keyScaledChildHeight), scaledChildHeight); int scaledWidth = scaledChildWidth; int scaledHeight = scaledChildHeight; if (displayRatio <= previewRatio) { if (isPortrait) { if (DEBUG) { LogUtils.v("Portrait"); } scaledHeight = (displayWidth * previewHeight) / previewWidth; scaledWidth = (scaledHeight * previewWidth) / previewHeight; } else { if (DEBUG) { LogUtils.v("Landscape"); } scaledWidth = (displayHeight * previewWidth) / previewHeight; scaledHeight = (scaledWidth * previewHeight) / previewWidth; } } else { if (isPortrait) { if (DEBUG) { LogUtils.v("Portrait"); // scaledWidth = (displayHeight * previewWidth) / previewHeight; // scaledHeight = (scaledWidth * previewHeight) / previewWidth; } } else { if (DEBUG) { LogUtils.v("Landscape"); // scaledHeight = (displayWidth * previewHeight) / previewWidth; // scaledWidth = (scaledHeight * previewWidth) / previewHeight; } } } if (DEBUG) { LogUtils.v("scaledWidth: " + scaledWidth); } if (DEBUG) { LogUtils.v("scaledHeight: " + scaledHeight); } PreferenceUtils.putInt(context, context.getString(R.string.keyScaledWidth), scaledWidth); PreferenceUtils.putInt(context, context.getString(R.string.keyScaledHeight), scaledHeight); return camera.new Size(scaledWidth, scaledHeight); } /** * JSON??? * * @param params * @return */ public static String toJson(Camera.Parameters params) { String[] data = params.flatten().split(";"); JSONObject json = new JSONObject(); for (String element : data) { String[] splits = element.split("="); String key = splits[0]; if (DEBUG) { LogUtils.v(key); } String value = splits.length > 1 ? splits[1] : ""; if (DEBUG) { LogUtils.v(value); } try { json.put(key, value); } catch (JSONException e) { e.printStackTrace(); } } return json.toString(); } /** * JSON??? * * @param params * @return */ public static String toJson(CamcorderProfile camcorderProfile) { JSONObject json = new JSONObject(); try { json.put("audioBitRate: ", camcorderProfile.audioBitRate); json.put("audioChannels: ", camcorderProfile.audioChannels); json.put("audioCodec: ", camcorderProfile.audioCodec); json.put("audioSampleRate: ", camcorderProfile.audioSampleRate); json.put("duration: ", camcorderProfile.duration); json.put("fileFormat: ", camcorderProfile.fileFormat); json.put("quality: ", camcorderProfile.quality); json.put("videoBitRate: ", camcorderProfile.videoBitRate); json.put("videoCodec: ", camcorderProfile.videoCodec); json.put("videoFrameHeight: ", camcorderProfile.videoFrameHeight); json.put("videoFrameRate: ", camcorderProfile.videoFrameRate); json.put("videoFrameWidth: ", camcorderProfile.videoFrameWidth); } catch (JSONException e) { e.printStackTrace(); } if (DEBUG) { LogUtils.v("camcorderProfile.audioBitRate: " + camcorderProfile.audioBitRate); LogUtils.v("camcorderProfile.audioChannels: " + camcorderProfile.audioChannels); LogUtils.v("camcorderProfile.audioCodec: " + camcorderProfile.audioCodec); LogUtils.v("camcorderProfile.audioSampleRate: " + camcorderProfile.audioSampleRate); LogUtils.v("camcorderProfile.duration: " + camcorderProfile.duration); LogUtils.v("camcorderProfile.fileFormat: " + camcorderProfile.fileFormat); LogUtils.v("camcorderProfile.quality: " + camcorderProfile.quality); LogUtils.v("camcorderProfile.videoBitRate: " + camcorderProfile.videoBitRate); LogUtils.v("camcorderProfile.videoCodec: " + camcorderProfile.videoCodec); LogUtils.v("camcorderProfile.videoFrameHeight: " + camcorderProfile.videoFrameHeight); LogUtils.v("camcorderProfile.videoFrameRate: " + camcorderProfile.videoFrameRate); LogUtils.v("camcorderProfile.videoFrameWidth: " + camcorderProfile.videoFrameWidth); } return json.toString(); } /** * ?? */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) public static boolean canDisableShutterSound(CameraInfo info) { boolean canDisableShutterSound = false; if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.JELLY_BEAN_MR1)) { canDisableShutterSound = info.canDisableShutterSound; } return canDisableShutterSound; } /** * ??? */ @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public static boolean isFaceDetectionSupported(Context context, Camera camera) { boolean isFaceDetectionSupported = false; int maxNumDetectedFaces = 0; if (AndroidUtils.isMoreThanBuildVersion(Build.VERSION_CODES.ICE_CREAM_SANDWICH)) { maxNumDetectedFaces = camera.getParameters().getMaxNumDetectedFaces(); isFaceDetectionSupported = maxNumDetectedFaces > 0; } PreferenceUtils.putBoolean(context, context.getString(R.string.keySupportFaceDetection), isFaceDetectionSupported); PreferenceUtils.putInt(context, context.getString(R.string.keyMaxNumDetectedFaces), maxNumDetectedFaces); return isFaceDetectionSupported; } }