Android 相机-纹理视图预览在某些设备中闪烁

Android 相机-纹理视图预览在某些设备中闪烁,android,android-textureview,Android,Android Textureview,我已经用TextureView实现了我的自定义CamerView,它工作得非常好。虽然在一些设备中,如Motorolla G4-棉花糖,联想KNote-棒棒糖相机预览闪烁,屏幕上出现绿色方形视图 这是我的评论 public class CameraTextureView extends TextureView implements TextureView.SurfaceTextureListener { private static final String TAG = CameraTextur

我已经用TextureView实现了我的自定义CamerView,它工作得非常好。虽然在一些设备中,如Motorolla G4-棉花糖,联想KNote-棒棒糖相机预览闪烁,屏幕上出现绿色方形视图

这是我的评论

public class CameraTextureView extends TextureView implements TextureView.SurfaceTextureListener {
private static final String TAG = CameraTextureView.class.getSimpleName();
private Camera mCamera;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
private SurfaceTexture mSurfaceTexture;
private Handler mHandler;
private Context mContext;

public void setCamera(Camera mCamera) {
    try {
        this.mCamera = mCamera;
        if (mCamera == null) {
            return;
        }
        startCameraPreview();
    } catch (Exception e) {
        FileLog.e(TAG, e);
    }
}

public Camera getCamera() {
    return mCamera;
}

public CameraTextureView(Context context, Camera mCamera) {
    super(context);
    try {
        this.setSurfaceTextureListener(this);
        this.mCamera = mCamera;
        this.mSurfaceTexture = getSurfaceTexture();
        this.mHandler = new Handler();
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        this.mContext = context;
    } catch (Exception e) {
        FileLog.e(TAG, e);
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    try {
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);

        if (mSupportedPreviewSizes != null) {
            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        }

        float ratio;
        if (mPreviewSize.height >= mPreviewSize.width)
            ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
        else
            ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;

        setMeasuredDimension(width, ApplicationLoader.getPreferences().isToShowTeamList() == true ? (int) (width * ratio) : height);
    } catch (Exception e) {
        FileLog.e(TAG, e);
    }
}

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
    try {
        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;
    } catch (Exception e) {
        FileLog.e(TAG, e);
    }
    return null;
}

public void startCameraPreview() {
    try {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    mCamera.setPreviewTexture(getSurfaceTexture());
                    Camera.Parameters parameters = mCamera.getParameters();
                    parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                    parameters.setRotation(90);
                    mCamera.setDisplayOrientation(90);
                    mCamera.setParameters(parameters);
                    mCamera.startPreview();
                } catch (Exception e) {
                    FileLog.e(TAG, e);
                }
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
    } catch (Exception e) {
        FileLog.e(TAG, e);
    }
}

private void setCameraDisplayOrientation(Context mContext, android.hardware.Camera camera) {
    try{
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        /*int rotation = mContext.getWindowManager().getDefaultDisplay().getRotation();*/
        Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        int rotation = display.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 result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror
        } else { // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }catch(Exception e){
        FileLog.e(TAG, e.toString());
    }
}

@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
    startCameraPreview();
}



@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}

@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
    return false;
}

@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
}
公共类CamerateTextReview扩展了TextureView实现了TextureView.SurfaceTextureListener{
私有静态最终字符串标记=cameratexturereview.class.getSimpleName();
私人摄像机麦卡梅拉;
私有列表msupportedpreviews;
私人摄像机。尺寸mPreviewSize;
私人表面结构;
私人经理人;
私有上下文;
公共摄像机(摄像机mCamera){
试一试{
this.mCamera=mCamera;
if(mCamera==null){
返回;
}
startCameraPreview();
}捕获(例外e){
FileLog.e(TAG,e);
}
}
公共摄像机{
返回mCamera;
}
公共摄像机评论(上下文,摄像机mCamera){
超级(上下文);
试一试{
this.setSurfaceTextureListener(this);
this.mCamera=mCamera;
this.mSurfaceTexture=getSurfaceTexture();
this.mHandler=新处理程序();
mSupportedPreviewSizes=mCamera.getParameters().getSupportedPreviewSizes();
this.mContext=上下文;
}捕获(例外e){
FileLog.e(TAG,e);
}
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
试一试{
最终整数宽度=resolveSize(getSuggestedMinimumWidth(),widthMeasureSpec);
最终整数高度=resolveSize(getSuggestedMinimumHeight(),heightMeasureSpec);
if(mSupportedPreviewSizes!=null){
mPreviewSize=getOptimalPreviewSize(MSSupportedPreviewSize、宽度、高度);
}
浮动比率;
如果(mPreviewSize.height>=mPreviewSize.width)
比率=(float)mPreviewSize.height/(float)mPreviewSize.width;
其他的
比率=(浮动)mPreviewSize.width/(浮动)mPreviewSize.height;
setMeasuredDimension(宽度,ApplicationLoader.getPreferences().isToShowTeamList()==true?(int)(宽度*比率):高度);
}捕获(例外e){
FileLog.e(TAG,e);
}
}
私人相机。大小getOptimalPreviewSize(列表大小,整数w,整数h){
试一试{
最终双纵横比公差=0.1;
双目标率=(双)高/低;
如果(size==null)返回null;
照相机。大小优化大小=空;
double minDiff=double.MAX_值;
int targetHeight=h;
用于(相机尺寸:尺寸){
双倍比率=(双倍)size.width/size.height;
如果(数学abs(比率-目标比率)>纵横比公差)继续;
if(数学绝对值(尺寸高度-目标光)