某些设备上的相机预览性能问题 [英] Camera Preview performance issue on some devices

查看:313
本文介绍了某些设备上的相机预览性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用android camera api创建一个相机应用程序,通过此示例: https://examples.javacodegeeks.com/android/core/hardware/camera-hardware/android-camera-example/



我根据我的需要做了一些改变,你可以看到下面的代码。问题是,背照相机的相机预览工作相当精细,我的LG G3设备,但在LG G4它变得太慢。它也适用于前置摄像头在两个设备上。



什么原因可能导致此问题?



CameraPreview:

  CameraPreview扩展SurfaceView实现SurfaceHolder.Callback {

private static String TAG =CameraPreview;

private SurfaceHolder mHolder;
私人相机mCamera;
private List< Size> mSupportedPreviewSizes;
private Size mPreviewSize;


public CameraPreview(Context context,Camera camera){
super(context);
mCamera = camera;

mHolder = getHolder();
mHolder.addCallback(this);
//弃用设置,但在3.0之前的Android版本中需要
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


}

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder){
try {
Log.d ,Surface Created ..);
if(mCamera == null){
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
} catch(IOException e){
Log.d(VIEW_LOG_TAG,Error setting camera preview:+ e.getMessage());
}

}

public void refreshCamera(Camera camera){
if(mHolder.getSurface()== null){
//预览曲面不存在
return;
}
//在进行更改之前停止预览
try {
mCamera.stopPreview();
} catch(Exception e){
// ignore:试图停止不存在的预览
}
//设置预览大小并进行任何调整大小,旋转或
//重新格式化改变这里
//用新设置开始预览
setCamera(camera);
try {
Log.d(TAG,RefreshCamera ..);
if(mCamera == null){
Log.d(TAG,Camera null);
}

Camera.Parameters parameters = mCamera.getParameters();
parameter.setPreviewSize(mPreviewSize.width,mPreviewSize.height);
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewDisplay(mHolder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
} catch(Exception e){
Log.d(VIEW_LOG_TAG,Error starting camera preview:+ e.getMessage());
}
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder,int i,int i1,int i2){

Log .d(TAG,Surface Changed ..);


refreshCamera(mCamera);
}

public void setCamera(Camera camera){
//设置相机实例的方法
mCamera = camera;
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder){

mCamera.release();
}

@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){
Log.d(TAG,onMeasure ..);
final int width = resolveSize(getSuggestedMinimumWidth(),widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(),heightMeasureSpec);
setMeasuredDimension(width,height);
if(mSupportedPreviewSizes == null){
mSupportedPreviewSizes = mCamera.getParameters()。getSupportedPreviewSizes();
} else {

mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes,width,height);
Log.d(TAG,mPreviewSize set .. Width:+ mPreviewSize.width +Height:+ mPreviewSize.height);
}
}

private Camera.Size getOptimalPreviewSize(List< Camera.Size> sizes,int w,int h){
final double ASPECT_TOLERANCE = 0.1;
double targetRatio =(double)h / w;

if(sizes == null)return null;

Camera.Size optimumSize = null;
double minDiff = Double.MAX_VALUE;

int targetHeight = h;

for(Camera.Size size:sizes){
double ratio =(double)size.width / size.height;
if(Math.abs(ratio - targetRatio)> ASPECT_TOLERANCE)continue;
if(Math.abs(size.height - targetHeight)< minDiff){
optimumSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}

if(optimalSize == null){
minDiff = Double.MAX_VALUE;
for(Camera.Size size:sizes){
if(Math.abs(size.height - targetHeight)< minDiff){
optimumSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimumSize;
}

}



如果需要,我可以共享Activity类。



谢谢..

解决方案

我有同样的问题使用表面视图。使用下面的预览class.its为我的所有设备屏幕。



public class SquareCameraPreview扩展SurfaceView {

  public static final String = SquareCameraPreview.class.getSimpleName(); 
private static final int INVALID_POINTER_ID = -1;

private static final int ZOOM_OUT = 0;
private static final int ZOOM_IN = 1;
private static final int ZOOM_DELTA = 1;

private static final int FOCUS_SQR_SIZE = 100;
private static final int FOCUS_MAX_BOUND = 1000;
private static final int FOCUS_MIN_BOUND = -FOCUS_MAX_BOUND;

private static final double ASPECT_RATIO = 3.0 / 4.0;
私人相机mCamera;

private float mLastTouchX;
private float mLastTouchY;

//用于缩放
private int mMaxZoom;
private boolean mIsZoomSupported;
private int mActivePointerId = INVALID_POINTER_ID;
private int mScaleFactor = 1;
private ScaleGestureDetector mScaleDetector;

//对焦
private boolean mIsFocus;
private boolean mIsFocusReady;
private Camera.Area mFocusArea;
private ArrayList< Camera.Area> mFocusAreas;

public SquareCameraPreview(Context context){
super(context);
init(context);
}

public SquareCameraPreview(Context context,AttributeSet attrs){
super(context,attrs);
init(context);
}

public SquareCameraPreview(Context context,AttributeSet attrs,int defStyle){
super(context,attrs,defStyle);
init(context);
}

private void init(Context context){
mScaleDetector = new ScaleGestureDetector(context,new ScaleListener());
mFocusArea = new Camera.Area(new Rect(),1000);
mFocusAreas = new ArrayList< Camera.Area>();
mFocusAreas.add(mFocusArea);
}

/ **
*测量视图及其内容以确定测量的宽度和
*测量的高度
* /
@Override
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);

final boolean isPortrait =
getResources()。getConfiguration()。orientation == Configuration.ORIENTATION_PORTRAIT;

if(isPortrait){
if(width> height * ASPECT_RATIO){
width =(int)(height * ASPECT_RATIO + 0.5);
} else {
height =(int)(width / ASPECT_RATIO + 0.5);
}
} else {
if(height> width * ASPECT_RATIO){
height =(int)(width * ASPECT_RATIO + 0.5);
} else {
width =(int)(height / ASPECT_RATIO + 0.5);
}
}

setMeasuredDimension(width,height);
}

public int getViewWidth(){
return getWidth();
}

public int getViewHeight(){
return getHeight();
}

public void setCamera(Camera camera){
mCamera = camera;

if(camera!= null){
Camera.Parameters params = camera.getParameters();
mIsZoomSupported = params.isZoomSupported();
if(mIsZoomSupported){
mMaxZoom = params.getMaxZoom();
}
}
}

@Override
public boolean onTouchEvent(MotionEvent event){
mScaleDetector.onTouchEvent(event);

final int action = event.getAction();
switch(action& MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:{
mIsFocus = true;

mLastTouchX = event.getX();
mLastTouchY = event.getY();

mActivePointerId = event.getPointerId(0);
break;
}
case MotionEvent.ACTION_UP:{
if(mIsFocus& mIsFocusReady){
handleFocus(mCamera.getParameters());
}
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_DOWN:{
mCamera.cancelAutoFocus();
mIsFocus = false;
break;
}
case MotionEvent.ACTION_CANCEL:{
mActivePointerId = INVALID_POINTER_ID;
break;
}
}

return true;
}

private void handleZoom(Camera.Parameters params){
int zoom = params.getZoom();
if(mScaleFactor == ZOOM_IN){
if(zoom< mMaxZoom)zoom + = ZOOM_DELTA;
} else if(mScaleFactor == ZOOM_OUT){
if(zoom> 0)zoom - = ZOOM_DELTA;
}
params.setZoom(zoom);
mCamera.setParameters(params);
}

private void handleFocus(Camera.Parameters params){
float x = mLastTouchX;
float y = mLastTouchY;

if(!setFocusBound(x,y))return;

List< String> supportedFocusModes = params.getSupportedFocusModes();
if(supportedFocusModes!= null
&& supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)){
Log.d(TAG,mFocusAreas.size()+);
params.setFocusAreas(mFocusAreas);
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
mCamera.setParameters(params);
mCamera.autoFocus(new Camera.AutoFocusCallback(){
@Override
public void onAutoFocus(boolean success,Camera camera){
//自动对焦完成后回调
}
});
}
}

public void setIsFocusReady(final boolean isFocusReady){
mIsFocusReady = isFocusReady;
}

private boolean setFocusBound(float x,float y){
int left =(int)(x - FOCUS_SQR_SIZE / 2);
int right =(int)(x + FOCUS_SQR_SIZE / 2);
int top =(int)(y - FOCUS_SQR_SIZE / 2);
int bottom =(int)(y + FOCUS_SQR_SIZE / 2);

if(FOCUS_MIN_BOUND> left || left> FOCUS_MAX_BOUND)return false;
if(FOCUS_MIN_BOUND> right || right> FOCUS_MAX_BOUND)return false;
if(FOCUS_MIN_BOUND> top || top> FOCUS_MAX_BOUND)return false;
if(FOCUS_MIN_BOUND> bottom || bottom> FOCUS_MAX_BOUND)return false;

mFocusArea.rect.set(left,top,right,bottom);

return true;
}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

@Override
public boolean onScale(ScaleGestureDetector detector){
mScaleFactor = int)detector.getScaleFactor();
handleZoom(mCamera.getParameters());
return true;
}
}

}


public class CameraFragment extends Fragment implements SurfaceHolder.Callback,Camera.PictureCallback {




  public static INT HIGH_RESOLUTION_WIDTH = 1000; 
public static int HIGH_RESOLUTION_HIGHT = 1500;
public static String clorie_count;
private long startTime = 0L;

public static final String TAG = CameraFragment.class.getSimpleName();
public static final String CAMERA_ID_KEY =camera_id;
public static final String CAMERA_FLASH_KEY =flash_mode;
public static final String IMAGE_INFO =image_info;

private static final int PICTURE_SIZE_MAX_WIDTH = 1280;
private static final int PREVIEW_SIZE_MAX_WIDTH = 640;

private int mCameraID;
private String mFlashMode;
私人相机mCamera;
private SquareCameraPreview mPreviewView;
private SurfaceHolder mSurfaceHolder;

private boolean mIsSafeToTakePhoto = false;

private ImageParameters mImageParameters;

private CameraOrientationListener mOrientationListener;
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
context = activity;
mOrientationListener = new CameraOrientationListener(context);
}

查看视图;
对话框列表

@SuppressLint(NewApi)
@Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,
Bundle savedInstanceState){

view = inflater.inflate(R.layout.camera_fragment,container,false);

if(savedInstanceState == null){
mCameraID = getBackCameraID();
mFlashMode = CameraSettingPreferences.getCameraFlashMode(getActivity());
mImageParameters = new ImageParameters();
} else {
mCameraID = savedInstanceState.getInt(CAMERA_ID_KEY);
mFlashMode = savedInstanceState.getString(CAMERA_FLASH_KEY);
mImageParameters = savedInstanceState.getParcelable(IMAGE_INFO);
}
mPreviewView =(SquareCameraPreview)view.findViewById(R.id.camerapreview);
mPreviewView.getHolder()。addCallback(CameraFragment.this);
mImageParameters.mIsPortrait = getResources()。getConfiguration()。orientation == Configuration.ORIENTATION_PORTRAIT;

capture_icon.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v){
// TODO自动生成方法stub
takePicture();
}
});
return view;
}
private void takePicture(){

if(mIsSafeToTakePhoto){
setSafeToTakePhoto(false);

mOrientationListener.rememberOrientation();

//捕获图像后发生快门回调。这可以
//用于触发一个声音,让用户知道图像是
Camera.ShutterCallback shutterCallback = null;

//当原始图像数据可用时,原始回调发生
Camera.PictureCallback raw = null;

//当缩放的,完全处理的
// postView图像可用时,postView回调发生。
Camera.PictureCallback postView = null;

//当压缩图像可用时,jpeg回调发生
mCamera.takePicture(shutterCallback,raw,postView,this);
}
}

private void setSafeToTakePhoto(final boolean isSafeToTakePhoto){
mIsSafeToTakePhoto = isSafeToTakePhoto;
}

private void setCameraFocusReady(final boolean isFocusReady){
if(this.mPreviewView!= null){
mPreviewView.setIsFocusReady(isFocusReady);
}
}
/ **
*确定当前显示方向并旋转相机预览
*据此
* /
private void decisionDisplayOrientation(){
CameraInfo cameraInfo = new CameraInfo();
Camera.getCameraInfo(mCameraID,cameraInfo);

//将窗口显示对齐到自然位置所需的顺时针旋转
int rotation = getActivity()。getWindowManager()。getDefaultDisplay()。getRotation();
int degree = 0;

开关(旋转){
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 displayOrientation;

// CameraInfo.Orientation是相对于设备自然位置的角度
//顺时针旋转(从自然位置顺时针旋转的角度)
if( cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT){
//方向是面对摄像机时的旋转角度
//摄像机图像匹配设备的自然方向
displayOrientation =( cameraInfo.orientation + degrees)%360;
displayOrientation =(360 - displayOrientation)%360;
} else {
displayOrientation =(cameraInfo.orientation - degrees + 360)%360;
}

mImageParameters.mDisplayOrientation = displayOrientation
mImageParameters.mLayoutOrientation = degrees;

mCamera.setDisplayOrientation(mImageParameters.mDisplayOrientation);
}
private void setupCamera(){
//不保存全局参数
Camera.Parameters parameters = mCamera.getParameters();

size bestPreviewSize = determineBestPreviewSize(parameters);
size bestPictureSize = determineBestPictureSize(parameters);

parameter.setPreviewSize(bestPreviewSize.width,bestPreviewSize.height);
parameter.setPictureSize(bestPictureSize.width,bestPictureSize.height);


//如果支持的话,设置连续图片焦点
if(parameters.getSupportedFocusModes()。contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
parameters。 setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}

final查看changeCameraFlashModeBtn = getView()。findViewById(R.id.flash);
List< String> flashModes = parameters.getSupportedFlashModes();
if(flashModes!= null&& flashModes.contains(mFlashMode)){
parameter.setFlashMode(mFlashMode);
changeCameraFlashModeBtn.setVisibility(View.VISIBLE);
} else {
changeCameraFlashModeBtn.setVisibility(View.INVISIBLE);
}

//锁定更改
mCamera.setParameters(parameters);
}
private size determineBestPreviewSize(Camera.Parameters parameters){
return decisionBestSize(parameters.getSupportedPreviewSizes(),PREVIEW_SIZE_MAX_WIDTH);
}

private size determineBestPictureSize(Camera.Parameters parameters){
return decisionBestSize(parameters.getSupportedPictureSizes(),PICTURE_SIZE_MAX_WIDTH);
}

private size determinationBestSize(List< Size> sizes,int widthThreshold){
size bestSize = null;
尺寸大小;
int numOfSizes = sizes.size();
for(int i = 0; i size = sizes.get(i);
boolean isDesireRatio =(size.width / 4)==(size.height / 3);
boolean isBetterSize =(bestSize == null)|| size.width> bestSize.width;

if(isDesireRatio&& isBetterSize){
bestSize = size;
}
}

if(bestSize == null){
Log.d(TAG,找不到最佳相机大小);
return sizes.get(sizes.size() - 1);
}

return bestSize;
}

/ **
*启动相机预览
* /
private void startCameraPreview(){
determineDisplayOrientation();
setupCamera();

try {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();

setSafeToTakePhoto(true);
setCameraFocusReady(true);
} catch(IOException e){
Log.d(TAG,由于IOException无法启动相机预览+ e);
e.printStackTrace();
}
}

private void getCamera(int cameraID){
try {
mCamera = Camera.open(cameraID);
mPreviewView.setCamera(mCamera);
} catch(Exception e){
Log.d(TAG,无法打开带有id的摄像机+ cameraID);
e.printStackTrace();
}
}

@Override
public void onPictureTaken(byte [] arg0,Camera arg1){
// TODO自动生成方法stub



这里你可以获取照片的BYTE [] arg0

转换为BITMAP或STROE INTO文件


}

@Override
public void surfaceChanged(SurfaceHolder arg0,int arg1,int arg2,
int arg3){
// TODO自动生成方法stub

}

@Override
public void surfaceCreated(SurfaceHolder holder){
// TODO自动生成的方法存根
mSurfaceHolder =持有人

getCamera(mCameraID);
startCameraPreview();
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0){
// TODO自动生成方法存根

}



私人静态类CameraOrientationListener extends OrientationEventListener {

private int mCurrentNormalizedOrientation;
private int mRememberedNormalOrientation;

public CameraOrientationListener(Context context){
super(context,SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
public void onOrientationChanged(int orientation){
if(orientation!= ORIENTATION_UNKNOWN){
mCurrentNormalizedOrientation = normalize(orientation);
}
}

/ **
* @param degrees设备自然位置的顺时针旋转量
* @return归一化度为0 ,90,180,270
* /
private int normalize(int degrees){
if(degrees> 315 || degrees< = 45){
return 0;
}

if(degrees> 45&& degrees< = 135){
return 90;
}

if(degrees> 135&& degrees< = 225){
return 180;
}

if(degrees> 225&& degrees< = 315){
return 270;
}

throw new RuntimeException(The physics as we know them are no more。Watch out for anomalies。
}

public void rememberOrientation(){
mRememberedNormalOrientation = mCurrentNormalizedOrientation;
}

public int getRememberedNormalOrientation(){
rememberOrientation();
return mRememberedNormalOrientation;
}
}
/ * @覆盖
public void onResume(){
super.onResume();

if(mCamera == null){
restartPreview();
}
} * /

@Override
public void onStop(){
mOrientationListener.disable();

//停止预览
if(mCamera!= null){
stopCameraPreview();
mCamera.release();
mCamera = null;
}
if(getKillStatus()){
android.os.Process.killProcess(android.os.Process.myPid());
}
// CameraSettingPreferences.saveCameraFlashMode(getActivity(),mFlashMode);

super.onStop();
}
@Override
public void onResume(){
super.onResume();
/ * if(camera!= null){
camera.stopPreview();
preview.setupCamera(null,isResolutionHigh);
camera.release();
camera = null;
}

int numCams = Camera.getNumberOfCameras();
if(numCams> 0){
try {
camera = Camera.open(0);
camera.startPreview();
preview.setupCamera(camera,isResolutionHigh);

} catch(RuntimeException ex){
// Toast.makeText(ctx,getString(R.string.camera_not_found),
// Toast.LENGTH_LONG) ;
}
} * /
if(mCamera == null){
restartPreview();
}

}
private void restartPreview(){
if(mCamera!= null){
stopCameraPreview
mCamera.release();
mCamera = null;
}

getCamera(mCameraID);
startCameraPreview();
}
/ **
*停止相机预览
* /
private void stopCameraPreview(){
setSafeToTakePhoto(false);
setCameraFocusReady(false);

//清除回调,停止面部检测
mCamera.stopPreview();
mPreviewView.setCamera(null);
}
private int getBackCameraID(){
return CameraInfo.CAMERA_FACING_BACK;
}

}




和您的XML文件


 < com .demo.camera.SquareCameraPreview android:id =@ + id / camerapreviewandroid:layout_width =match_parentandroid:layout_height =wrap_content/>  

div>



ImageParameter类



  public class ImageParameters implements Parcelable {public boolean mIsPortrait; public int mDisplayOrientation; public int mLayoutOrientation; public int mCoverHeight,mCoverWidth; public int mPreviewHeight,mPreviewWidth; public ImageParameters(Parcel in){mIsPortrait =(in.readByte()== 1); mDisplayOrientation = in.readInt() mLayoutOrientation = in.readInt(); mCoverHeight = in.readInt(); mCoverWidth = in.readInt(); mPreviewHeight = in.readInt(); mPreviewWidth = in.readInt(); } public ImageParameters(){} public int calculateCoverWidthHeight(){return Math.abs(mPreviewHeight  -  mPreviewWidth)/ 2; } public int getAnimationParameter(){return mIsPortrait? mCoverHeight:mCoverWidth; } public boolean isPortrait(){return mIsPortrait; } public ImageParameters createCopy(){ImageParameters imageParameters = new ImageParameters(); imageParameters.mIsPortrait = mIsPortrait; imageParameters.mDisplayOrientation = mDisplayOrientation; imageParameters.mLayoutOrientation = mLayoutOrientation; imageParameters.mCoverHeight = mCoverHeight; imageParameters.mCoverWidth = mCoverWidth; imageParameters.mPreviewHeight = mPreviewHeight; imageParameters.mPreviewWidth = mPreviewWidth; return imageParameters; } + mCoverHeight +width:+ mCoverWidth +\ npreview height:+ mPreviewHeight +width:+ mPreviewHeight + + mPreviewWidth; } @Override public int describeContents(){return 0; } @Override public void writeToParcel(Parcel dest,int flags){dest.writeByte((byte)(mIsPortrait?1:0)); dest.writeInt(mDisplayOrientation); dest.writeInt(mLayoutOrientation); dest.writeInt(mCoverHeight); dest.writeInt(mCoverWidth); dest.writeInt(mPreviewHeight); dest.writeInt(mPreviewWidth); } public static final Creator< ImageParameters> CREATOR = new Parcelable.Creator< ImageParameters>(){@覆盖public ImageParameters createFromParcel(Parcel source){return new ImageParameters(source); } @Override public ImageParameters [] newArray(int size){return new ImageParameters [size]; 



另一个类需要相机设置首选项

p>

  public class CameraSettingPreferences {private static final String FLASH_MODE =squarecamera__flash_mode; private static SharedPreferences getCameraSettingPreferences(@NonNull final Context context){return context.getSharedPreferences(com.desmond.squarecamera,Context.MODE_PRIVATE); } protected static void saveCameraFlashMode(@NonNull final Context context,@NonNull final String cameraFlashMode){final SharedPreferences preferences = getCameraSettingPreferences(context); if(preferences!= null){final SharedPreferences.Editor editor = preferences.edit(); editor.putString(FLASH_MODE,cameraFlashMode); editor.apply(); }} public static String getCameraFlashMode(@NonNull final Context context){final SharedPreferences preference = getCameraSettingPreferences(context); if(preferences!= null){return preferences.getString(FLASH_MODE,Camera.Parameters.FLASH_MODE_AUTO); } return Camera.Parameters.FLASH_MODE_AUTO; }} 



如果您有任何疑问, p>

I am creating a camera application using android camera api by this example: https://examples.javacodegeeks.com/android/core/hardware/camera-hardware/android-camera-example/

I made some changes according to my needs and you can see the code below. The problem is, camera preview for back camera works quite fine on my LG G3 device but on LG G4 it gets too slow. It also works fine with front camera on both devices.

What can cause this problem ?

CameraPreview:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{

private static String TAG = "CameraPreview";

private SurfaceHolder mHolder;
private Camera mCamera;
private List<Size> mSupportedPreviewSizes;
private Size mPreviewSize;


public CameraPreview(Context context, Camera camera){
    super(context);
    mCamera = camera;

    mHolder = getHolder();
    mHolder.addCallback(this);
    // deprecated setting, but required on Android versions prior to 3.0
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


}

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
    try{
        Log.d(TAG, "Surface Created..");
        if(mCamera == null){
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();
        }
    } catch (IOException e) {
        Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
    }

}

public void refreshCamera(Camera camera) {
    if (mHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }
    // stop preview before making changes
    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        // ignore: tried to stop a non-existent preview
    }
    // set preview size and make any resize, rotate or
    // reformatting changes here
    // start preview with new settings
    setCamera(camera);
    try {
        Log.d(TAG,"RefreshCamera..");
        if(mCamera == null){
            Log.d(TAG,"Camera null");
        }

        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setParameters(parameters);
        mCamera.setPreviewDisplay(mHolder);
        mCamera.setPreviewDisplay(mHolder);
        mCamera.setDisplayOrientation(90);
        mCamera.startPreview();
    } catch (Exception e) {
        Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
    }
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    Log.d(TAG, "Surface Changed..");


    refreshCamera(mCamera);
}

public void setCamera(Camera camera) {
    //method to set a camera instance
    mCamera = camera;
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

     mCamera.release();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Log.d(TAG,"onMeasure..");
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
    setMeasuredDimension(width, height);
    if(mSupportedPreviewSizes==null){
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
    }else{

        mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        Log.d(TAG, "mPreviewSize set.. Width: " + mPreviewSize.width+" Height: " + mPreviewSize.height);
    }
}

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio=(double)h / w;

    if (sizes == null) return null;

    Camera.Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    for (Camera.Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - 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 (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

}

I can share the Activity class if its needed..

Thanks..

解决方案

I had the same problem using surface view .use the below preview class.its working for me for all the device screen.

public class SquareCameraPreview extends SurfaceView {

public static final String TAG = SquareCameraPreview.class.getSimpleName();
private static final int INVALID_POINTER_ID = -1;

private static final int ZOOM_OUT = 0;
private static final int ZOOM_IN = 1;
private static final int ZOOM_DELTA = 1;

private static final int FOCUS_SQR_SIZE = 100;
private static final int FOCUS_MAX_BOUND = 1000;
private static final int FOCUS_MIN_BOUND = -FOCUS_MAX_BOUND;

private static final double ASPECT_RATIO = 3.0 / 4.0;
private Camera mCamera;

private float mLastTouchX;
private float mLastTouchY;

// For scaling
private int mMaxZoom;
private boolean mIsZoomSupported;
private int mActivePointerId = INVALID_POINTER_ID;
private int mScaleFactor = 1;
private ScaleGestureDetector mScaleDetector;

// For focus
private boolean mIsFocus;
private boolean mIsFocusReady;
private Camera.Area mFocusArea;
private ArrayList<Camera.Area> mFocusAreas;

public SquareCameraPreview(Context context) {
    super(context);
    init(context);
}

public SquareCameraPreview(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
}

public SquareCameraPreview(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

private void init(Context context) {
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    mFocusArea = new Camera.Area(new Rect(), 1000);
    mFocusAreas = new ArrayList<Camera.Area>();
    mFocusAreas.add(mFocusArea);
}

/**
 * Measure the view and its content to determine the measured width and the
 * measured height
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int height = MeasureSpec.getSize(heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);

    final boolean isPortrait =
            getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;

    if (isPortrait) {
        if (width > height * ASPECT_RATIO) {
            width = (int) (height * ASPECT_RATIO + 0.5);
        } else {
            height = (int) (width / ASPECT_RATIO + 0.5);
        }
    } else {
        if (height > width * ASPECT_RATIO) {
            height = (int) (width * ASPECT_RATIO + 0.5);
        } else {
            width = (int) (height / ASPECT_RATIO + 0.5);
        }
    }

    setMeasuredDimension(width, height);
}

public int getViewWidth() {
    return getWidth();
}

public int getViewHeight() {
    return getHeight();
}

public void setCamera(Camera camera) {
    mCamera = camera;

    if (camera != null) {
        Camera.Parameters params = camera.getParameters();
        mIsZoomSupported = params.isZoomSupported();
        if (mIsZoomSupported) {
            mMaxZoom = params.getMaxZoom();
        }
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    mScaleDetector.onTouchEvent(event);

    final int action = event.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN: {
            mIsFocus = true;

            mLastTouchX = event.getX();
            mLastTouchY = event.getY();

            mActivePointerId = event.getPointerId(0);
            break;
        }
        case MotionEvent.ACTION_UP: {
            if (mIsFocus && mIsFocusReady) {
                handleFocus(mCamera.getParameters());
            }
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }
        case MotionEvent.ACTION_POINTER_DOWN: {
            mCamera.cancelAutoFocus();
            mIsFocus = false;
            break;
        }
        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }
    }

    return true;
}

private void handleZoom(Camera.Parameters params) {
    int zoom = params.getZoom();
    if (mScaleFactor == ZOOM_IN) {
        if (zoom < mMaxZoom) zoom += ZOOM_DELTA;
    } else if (mScaleFactor == ZOOM_OUT) {
        if (zoom > 0) zoom -= ZOOM_DELTA;
    }
    params.setZoom(zoom);
    mCamera.setParameters(params);
}

private void handleFocus(Camera.Parameters params) {
    float x = mLastTouchX;
    float y = mLastTouchY;

    if (!setFocusBound(x, y)) return;

    List<String> supportedFocusModes = params.getSupportedFocusModes();
    if (supportedFocusModes != null
            && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
        Log.d(TAG, mFocusAreas.size() + "");
        params.setFocusAreas(mFocusAreas);
        params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        mCamera.setParameters(params);
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                // Callback when the auto focus completes
            }
        });
    }
}

public void setIsFocusReady(final boolean isFocusReady) {
    mIsFocusReady = isFocusReady;
}

private boolean setFocusBound(float x, float y) {
    int left = (int) (x - FOCUS_SQR_SIZE / 2);
    int right = (int) (x + FOCUS_SQR_SIZE / 2);
    int top = (int) (y - FOCUS_SQR_SIZE / 2);
    int bottom = (int) (y + FOCUS_SQR_SIZE / 2);

    if (FOCUS_MIN_BOUND > left || left > FOCUS_MAX_BOUND) return false;
    if (FOCUS_MIN_BOUND > right || right > FOCUS_MAX_BOUND) return false;
    if (FOCUS_MIN_BOUND > top || top > FOCUS_MAX_BOUND) return false;
    if (FOCUS_MIN_BOUND > bottom || bottom > FOCUS_MAX_BOUND) return false;

    mFocusArea.rect.set(left, top, right, bottom);

    return true;
}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        mScaleFactor = (int) detector.getScaleFactor();
        handleZoom(mCamera.getParameters());
        return true;
    }
}

}

public class CameraFragment extends Fragment implements SurfaceHolder.Callback, Camera.PictureCallback {

public static int HIGH_RESOLUTION_WIDTH=1000;
public static int HIGH_RESOLUTION_HIGHT=1500;
public static String clorie_count;
private long startTime = 0L;

public static final String TAG = CameraFragment.class.getSimpleName();
public static final String CAMERA_ID_KEY = "camera_id";
public static final String CAMERA_FLASH_KEY = "flash_mode";
public static final String IMAGE_INFO = "image_info";

private static final int PICTURE_SIZE_MAX_WIDTH = 1280;
private static final int PREVIEW_SIZE_MAX_WIDTH = 640;

private int mCameraID;
private String mFlashMode;
private Camera mCamera;
private SquareCameraPreview mPreviewView;
private SurfaceHolder mSurfaceHolder;

private boolean mIsSafeToTakePhoto = false;

private ImageParameters mImageParameters;

private CameraOrientationListener mOrientationListener;
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    context = activity;
    mOrientationListener = new CameraOrientationListener(context);
}

View view;
Dialog listDialog;

@SuppressLint("NewApi")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.camera_fragment, container, false);

    if (savedInstanceState == null) {
            mCameraID = getBackCameraID();
            mFlashMode = CameraSettingPreferences.getCameraFlashMode(getActivity());
            mImageParameters = new ImageParameters();
        } else {
            mCameraID = savedInstanceState.getInt(CAMERA_ID_KEY);
            mFlashMode = savedInstanceState.getString(CAMERA_FLASH_KEY);
            mImageParameters = savedInstanceState.getParcelable(IMAGE_INFO);
        }
   mPreviewView = (SquareCameraPreview) view.findViewById(R.id.camerapreview);
         mPreviewView.getHolder().addCallback(CameraFragment.this);
         mImageParameters.mIsPortrait =getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;

         capture_icon.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            takePicture();
        }
    });
return view;
}
         private void takePicture() {

            if (mIsSafeToTakePhoto) {
                setSafeToTakePhoto(false);

                mOrientationListener.rememberOrientation();

                // Shutter callback occurs after the image is captured. This can
                // be used to trigger a sound to let the user know that image is taken
                Camera.ShutterCallback shutterCallback = null;

                // Raw callback occurs when the raw image data is available
                Camera.PictureCallback raw = null;

                // postView callback occurs when a scaled, fully processed
                // postView image is available.
                Camera.PictureCallback postView = null;

                // jpeg callback occurs when the compressed image is available
                mCamera.takePicture(shutterCallback, raw, postView, this);
            }
        }        

        private void setSafeToTakePhoto(final boolean isSafeToTakePhoto) {
        mIsSafeToTakePhoto = isSafeToTakePhoto;
    }

    private void setCameraFocusReady(final boolean isFocusReady) {
        if (this.mPreviewView != null) {
            mPreviewView.setIsFocusReady(isFocusReady);
        }
    }
    /**
     * Determine the current display orientation and rotate the camera preview
     * accordingly
     */
    private void determineDisplayOrientation() {
        CameraInfo cameraInfo = new CameraInfo();
        Camera.getCameraInfo(mCameraID, cameraInfo);

        // Clockwise rotation needed to align the window display to the natural position
        int rotation = getActivity().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 displayOrientation;

        // CameraInfo.Orientation is the angle relative to the natural position of the device
        // in clockwise rotation (angle that is rotated clockwise from the natural position)
        if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
            // Orientation is angle of rotation when facing the camera for
            // the camera image to match the natural orientation of the device
            displayOrientation = (cameraInfo.orientation + degrees) % 360;
            displayOrientation = (360 - displayOrientation) % 360;
        } else {
            displayOrientation = (cameraInfo.orientation - degrees + 360) % 360;
        }

        mImageParameters.mDisplayOrientation = displayOrientation;
        mImageParameters.mLayoutOrientation = degrees;

        mCamera.setDisplayOrientation(mImageParameters.mDisplayOrientation);
    }
    private void setupCamera() {
        // Never keep a global parameters
        Camera.Parameters parameters = mCamera.getParameters();

        Size bestPreviewSize = determineBestPreviewSize(parameters);
        Size bestPictureSize = determineBestPictureSize(parameters);

        parameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
        parameters.setPictureSize(bestPictureSize.width, bestPictureSize.height);


        // Set continuous picture focus, if it's supported
        if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        }

        final View changeCameraFlashModeBtn = getView().findViewById(R.id.flash);
        List<String> flashModes = parameters.getSupportedFlashModes();
        if (flashModes != null && flashModes.contains(mFlashMode)) {
            parameters.setFlashMode(mFlashMode);
            changeCameraFlashModeBtn.setVisibility(View.VISIBLE);
        } else {
            changeCameraFlashModeBtn.setVisibility(View.INVISIBLE);
        }

        // Lock in the changes
        mCamera.setParameters(parameters);
    }
    private Size determineBestPreviewSize(Camera.Parameters parameters) {
        return determineBestSize(parameters.getSupportedPreviewSizes(), PREVIEW_SIZE_MAX_WIDTH);
    }

    private Size determineBestPictureSize(Camera.Parameters parameters) {
        return determineBestSize(parameters.getSupportedPictureSizes(), PICTURE_SIZE_MAX_WIDTH);
    }

    private Size determineBestSize(List<Size> sizes, int widthThreshold) {
        Size bestSize = null;
        Size size;
        int numOfSizes = sizes.size();
        for (int i = 0; i < numOfSizes; i++) {
            size = sizes.get(i);
            boolean isDesireRatio = (size.width / 4) == (size.height / 3);
            boolean isBetterSize = (bestSize == null) || size.width > bestSize.width;

            if (isDesireRatio && isBetterSize) {
                bestSize = size;
            }
        }

        if (bestSize == null) {
            Log.d(TAG, "cannot find the best camera size");
            return sizes.get(sizes.size() - 1);
        }

        return bestSize;
    }

     /**
     * Start the camera preview
     */
    private void startCameraPreview() {
        determineDisplayOrientation();
        setupCamera();

        try {
            mCamera.setPreviewDisplay(mSurfaceHolder);
            mCamera.startPreview();

            setSafeToTakePhoto(true);
            setCameraFocusReady(true);
        } catch (IOException e) {
            Log.d(TAG, "Can't start camera preview due to IOException " + e);
            e.printStackTrace();
        }
    }

    private void getCamera(int cameraID) {
        try {
            mCamera = Camera.open(cameraID);
            mPreviewView.setCamera(mCamera);
        } catch (Exception e) {
            Log.d(TAG, "Can't open camera with id " + cameraID);
            e.printStackTrace();
        }
    }

    @Override
    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub



        HERE YOU GET THE PHOTO BYTE[] arg0

        CONVERT IT TO BITMAP OR STROE INTO A FILE


    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
            int arg3) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
         mSurfaceHolder = holder;

            getCamera(mCameraID);
            startCameraPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub

    } 



        private static class CameraOrientationListener extends OrientationEventListener {

            private int mCurrentNormalizedOrientation;
            private int mRememberedNormalOrientation;

            public CameraOrientationListener(Context context) {
                super(context, SensorManager.SENSOR_DELAY_NORMAL);
            }

            @Override
            public void onOrientationChanged(int orientation) {
                if (orientation != ORIENTATION_UNKNOWN) {
                    mCurrentNormalizedOrientation = normalize(orientation);
                }
            }

            /**
             * @param degrees Amount of clockwise rotation from the device's natural position
             * @return Normalized degrees to just 0, 90, 180, 270
             */
            private int normalize(int degrees) {
                if (degrees > 315 || degrees <= 45) {
                    return 0;
                }

                if (degrees > 45 && degrees <= 135) {
                    return 90;
                }

                if (degrees > 135 && degrees <= 225) {
                    return 180;
                }

                if (degrees > 225 && degrees <= 315) {
                    return 270;
                }

                throw new RuntimeException("The physics as we know them are no more. Watch out for anomalies.");
            }

            public void rememberOrientation() {
                mRememberedNormalOrientation = mCurrentNormalizedOrientation;
            }

            public int getRememberedNormalOrientation() {
                rememberOrientation();
                return mRememberedNormalOrientation;
            }
        }
        /*@Override
        public void onResume() {
            super.onResume();

            if (mCamera == null) {
                restartPreview();
            }
        }*/

        @Override
        public void onStop() {
            mOrientationListener.disable();

            // stop the preview
            if (mCamera != null) {
                stopCameraPreview();
                mCamera.release();
                mCamera = null;
            }
            if (getKillStatus()) {
                android.os.Process.killProcess(android.os.Process.myPid());
            }
           // CameraSettingPreferences.saveCameraFlashMode(getActivity(), mFlashMode);

            super.onStop();
        }
        @Override
        public void onResume() {
            super.onResume();
            /*if (camera != null) {
                camera.stopPreview();
                preview.setupCamera(null,isResolutionHigh);
                camera.release();
                camera = null;
            }

            int numCams = Camera.getNumberOfCameras();
            if (numCams > 0) {
                try {
                    camera = Camera.open(0);
                    camera.startPreview();
                    preview.setupCamera(camera,isResolutionHigh);

                } catch (RuntimeException ex) {
                    // Toast.makeText(ctx, getString(R.string.camera_not_found),
                    // Toast.LENGTH_LONG).show();
                }
            }*/
            if (mCamera == null) {
                restartPreview();
            }

        }
        private void restartPreview() {
            if (mCamera != null) {
                stopCameraPreview();
                mCamera.release();
                mCamera = null;
            }

            getCamera(mCameraID);
            startCameraPreview();
        }
        /**
         * Stop the camera preview
         */
        private void stopCameraPreview() {
            setSafeToTakePhoto(false);
            setCameraFocusReady(false);

            // Nulls out callbacks, stops face detection
            mCamera.stopPreview();
            mPreviewView.setCamera(null);
        }
        private int getBackCameraID() {
            return CameraInfo.CAMERA_FACING_BACK;
        }

}        

AND YOUR XML FILE

<com.demo.camera.SquareCameraPreview
        android:id="@+id/camerapreview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

ImageParameter Class

public class ImageParameters implements Parcelable {

    public boolean mIsPortrait;

    public int mDisplayOrientation;
    public int mLayoutOrientation;

    public int mCoverHeight, mCoverWidth;
    public int mPreviewHeight, mPreviewWidth;

    public ImageParameters(Parcel in) {
        mIsPortrait = (in.readByte() == 1);

        mDisplayOrientation = in.readInt();
        mLayoutOrientation = in.readInt();

        mCoverHeight = in.readInt();
        mCoverWidth = in.readInt();
        mPreviewHeight = in.readInt();
        mPreviewWidth = in.readInt();
    }

    public ImageParameters() {}

    public int calculateCoverWidthHeight() {
       return Math.abs(mPreviewHeight - mPreviewWidth) / 2;
    }

    public int getAnimationParameter() {
        return mIsPortrait ? mCoverHeight : mCoverWidth;
    }

    public boolean isPortrait() {
        return mIsPortrait;
    }

    public ImageParameters createCopy() {
        ImageParameters imageParameters = new ImageParameters();

        imageParameters.mIsPortrait = mIsPortrait;
        imageParameters.mDisplayOrientation = mDisplayOrientation;
        imageParameters.mLayoutOrientation = mLayoutOrientation;

        imageParameters.mCoverHeight = mCoverHeight;
        imageParameters.mCoverWidth = mCoverWidth;
        imageParameters.mPreviewHeight = mPreviewHeight;
        imageParameters.mPreviewWidth = mPreviewWidth;

        return imageParameters;
    }

    public String getStringValues() {
        return "is Portrait: " + mIsPortrait + "," +
                "\ncover height: " + mCoverHeight + " width: " + mCoverWidth
                + "\npreview height: " + mPreviewHeight + " width: " + mPreviewWidth;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeByte((byte) (mIsPortrait ? 1 : 0));

        dest.writeInt(mDisplayOrientation);
        dest.writeInt(mLayoutOrientation);

        dest.writeInt(mCoverHeight);
        dest.writeInt(mCoverWidth);
        dest.writeInt(mPreviewHeight);
        dest.writeInt(mPreviewWidth);
    }

    public static final Creator<ImageParameters> CREATOR = new Parcelable.Creator<ImageParameters>() {
        @Override
        public ImageParameters createFromParcel(Parcel source) {
            return new ImageParameters(source);
        }

        @Override
        public ImageParameters[] newArray(int size) {
            return new ImageParameters[size];
        }
    };
}

Another class you need camera setting preference

public class CameraSettingPreferences {

    private static final String FLASH_MODE = "squarecamera__flash_mode";

    private static SharedPreferences getCameraSettingPreferences(@NonNull final Context context) {
        return context.getSharedPreferences("com.desmond.squarecamera", Context.MODE_PRIVATE);
    }

    protected static void saveCameraFlashMode(@NonNull final Context context, @NonNull final String cameraFlashMode) {
        final SharedPreferences preferences = getCameraSettingPreferences(context);

        if (preferences != null) {
            final SharedPreferences.Editor editor = preferences.edit();
            editor.putString(FLASH_MODE, cameraFlashMode);
            editor.apply();
        }
    }

    public static String getCameraFlashMode(@NonNull final Context context) {
        final SharedPreferences preferences = getCameraSettingPreferences(context);

        if (preferences != null) {
            return preferences.getString(FLASH_MODE, Camera.Parameters.FLASH_MODE_AUTO);
        }

        return Camera.Parameters.FLASH_MODE_AUTO;
    }
}

Let me know if you have any doubts.

这篇关于某些设备上的相机预览性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆