Android 安卓摄像头应用程序在onResume()后冻结黑屏

Android 安卓摄像头应用程序在onResume()后冻结黑屏,android,android-camera,surfaceview,onresume,onpause,Android,Android Camera,Surfaceview,Onresume,Onpause,我正在开发一个类似camscanner的应用程序。在我的应用程序中,我调用了一个摄像头api。当应用程序第一次打开时,我按下相机按钮,它就工作了,但当我点击主页按钮并再次打开我的应用程序时,它会冻结并显示一个黑屏,而应用程序不会崩溃。我发现了类似的问题,但没有一个能给我一个正确的答案,我知道我可能必须在onResume或onPause中更改一些内容,并需要帮助来找出什么 下面是我的相机屏幕活动: 公共类摄像机屏幕扩展活动{ ImageView image; Activity context; P

我正在开发一个类似camscanner的应用程序。在我的应用程序中,我调用了一个摄像头api。当应用程序第一次打开时,我按下相机按钮,它就工作了,但当我点击主页按钮并再次打开我的应用程序时,它会冻结并显示一个黑屏,而应用程序不会崩溃。我发现了类似的问题,但没有一个能给我一个正确的答案,我知道我可能必须在onResume或onPause中更改一些内容,并需要帮助来找出什么

下面是我的相机屏幕活动:

公共类摄像机屏幕扩展活动{

ImageView image;
Activity context;
Preview preview;
Camera camera;
Button exitButton;
ImageView fotoButton;
LinearLayout progressLayout;
String path = "/sdcard/KutCamera/cache/images/";
FrameLayout frame;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera_layout);

    context=this;

    fotoButton = (ImageView) findViewById(R.id.imageView_foto);
    exitButton = (Button) findViewById(R.id.button_exit);
    image = (ImageView) findViewById(R.id.imageView_photo);
    progressLayout = (LinearLayout) findViewById(R.id.progress_layout);

    preview = new Preview(this,
            (SurfaceView) findViewById(R.id.KutCameraFragment));
    frame = (FrameLayout) findViewById(R.id.preview);
    frame.addView(preview);
    preview.setKeepScreenOn(true);
    fotoButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            try {
                takeFocusedPicture();
            } catch (Exception e) {

            }
            exitButton.setClickable(true);
            fotoButton.setClickable(false);
            progressLayout.setVisibility(View.VISIBLE);
        }
    });
}


@Override
protected void onPause() {
    super.onPause();
    //releaseMediaRecorder();       // if you are using MediaRecorder, release it first
    //releaseCamera();  
    if(null != camera){
        camera.release();
        camera = null;
    }
    frame.removeView(preview);
    preview = null;// release the camera immediately on pause event
}



private void releaseCamera(){

    if (camera != null){
        camera.release();        // release the camera for other applications
        camera = null;
    }
}


@Override
protected void onResume() {
    super.onResume();
    // TODO Auto-generated method stub
    if(camera==null){

        Log.d("Camera tes", "Camera==null");
        //camera.setPreviewCallback(null);
    camera = Camera.open();
    camera.startPreview();

    camera.setErrorCallback(new ErrorCallback() {
        public void onError(int error, Camera mcamera) {

            camera.release();
            camera = Camera.open();
            Log.d("Camera died", "error camera");

        }
    });

    }
    if (camera != null) {
        //camera.setPreviewCallback(null);
        Log.d("Camera tes", "Camera!=null");
        if (Build.VERSION.SDK_INT >= 14)
            setCameraDisplayOrientation(context,
                    CameraInfo.CAMERA_FACING_BACK, camera);
        preview.setCamera(camera);
    }

}


private void setCameraDisplayOrientation(Activity activity, int cameraId,
        android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.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 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);
}



Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {

        try{
        camera.takePicture(mShutterCallback, null, jpegCallback);
        }catch(Exception e){

        }

    }
};

Camera.ShutterCallback mShutterCallback = new ShutterCallback() {

    @Override
    public void onShutter() {
        // TODO Auto-generated method stub

    }
};
public void takeFocusedPicture() {
    camera.autoFocus(mAutoFocusCallback);

}

PictureCallback rawCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
        // Log.d(TAG, "onPictureTaken - raw");
    }
};

PictureCallback jpegCallback = new PictureCallback() {
    @SuppressWarnings("deprecation")
    public void onPictureTaken(byte[] data, Camera camera) {

        FileOutputStream outStream = null;
        Calendar c = Calendar.getInstance();
        File videoDirectory = new File(path);

        if (!videoDirectory.exists()) {
            videoDirectory.mkdirs();
        }

        try {
            // Write to SD Card
            outStream = new FileOutputStream(path + c.getTime().getSeconds() + ".jpg");
            outStream.write(data);
            outStream.close();


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }


        Bitmap realImage;
         final BitmapFactory.Options options = new BitmapFactory.Options();
          options.inSampleSize = 5;

            options.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared

            options.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future


        realImage = BitmapFactory.decodeByteArray(data,0,data.length,options);
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(path + c.getTime().getSeconds()
                    + ".jpg");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            Log.d("EXIF value",
                    exif.getAttribute(ExifInterface.TAG_ORIENTATION));
            if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("1")) {
                realImage = rotate(realImage, 90);
            } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("8")) {
                realImage = rotate(realImage, 90);
            } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("3")) {
                realImage = rotate(realImage, 90);
            } else if (exif.getAttribute(ExifInterface.TAG_ORIENTATION)
                    .equalsIgnoreCase("0")) {
                realImage = rotate(realImage, 90);
            }
        } catch (Exception e) {

        }

        image.setImageBitmap(realImage);



        fotoButton.setClickable(true);
        camera.startPreview();
        progressLayout.setVisibility(View.GONE);
        exitButton.setClickable(true);

    }
};

public static Bitmap rotate(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
            source.getHeight(), matrix, false);
}

}
这是我的预习课:

类预览扩展视图组实现SurfaceHolder.Callback{ 私有最终字符串标记=“预览”

SurfaceView mSurfaceView;
表面粗糙度;
国际高度最大值;
int-widthmax;
大小mPreviewSize;
列出MSSupportedPreviewsizes;
麦克默拉照相机;
@抑制警告(“弃用”)
预览(上下文,SurfaceView sv){
超级(上下文);
mSurfaceView=sv;
//addView(mSurfaceView);
mHolder=mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE\u TYPE\u PUSH\u缓冲区);
}
公共摄像机(摄像机){
mCamera=摄像机;
if(mCamera!=null){
mSupportedPreviewSizes=mCamera.getParameters().getSupportedPictureSizes();
requestLayout();
//获取相机参数
Camera.Parameters params=mCamera.getParameters();
List focusModes=params.getSupportedFocusModes();
if(focusModes.contains(Camera.Parameters.FOCUS\u MODE\u AUTO)){
//设置焦点模式
params.setFocusMode(摄像头.Parameters.FOCUS_MODE_AUTO);
//设置相机参数
mCamera.setParameters(参数);
}
}
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
//我们故意忽略儿童的测量,因为这是一种
//包装到将摄影机预览居中的SurfaceView
//我想把它拉长。
最终整数宽度=resolveSize(getSuggestedMinimumWidth(),widthMeasureSpec);
最终整数高度=resolveSize(getSuggestedMinimumHeight(),heightMeasureSpec);
设置测量尺寸(宽度、高度);
if(mSupportedPreviewSizes!=null){
mPreviewSize=maxSize();
}
}
公共大小maxSize(){
Size sizeMax=mSupportedPreviewSizes.get(0);
maxsize=mSupportedPreviewSizes.get(0)
.height*mSupportedPreviewSizes.get(0).width;
用于(大小:mSupportedPreviewSizes){
if(size.height*size.width>sizeMax.width*sizeMax.height){
sizeMax=尺寸;
}
}
返回sizeMax;
}
@凌驾
仅受保护的void布局(布尔值已更改、int l、int t、int r、int b){
如果(已更改&&getChildCount()>0){
最终视图子对象=getChildAt(0);
最终整数宽度=r-l;
最终内部高度=b-t;
int previewWidth=宽度;
亮度=高度;
if(mPreviewSize!=null){
previewWidth=mPreviewSize.width;
PreviewView=mPreviewSize.height;
}
//将子曲面视图居中放置在父曲面视图中。
如果(宽度*预览宽度>高度*预览宽度){
最终整数缩放儿童宽度=预览宽度*高度/预览宽度;
布局((宽度-scaledChildWidth)/2,0,
(宽度+缩放儿童宽度)/2,高度);
}否则{
最终int scaledChildHeight=预览视图*宽度/预览宽度;
布局(0,(高度-缩放儿童高度)/2,
宽度(高度+缩放儿童高度)/2);
}
}
}
已创建的公共空白表面(表面持有人){
//曲面已创建,获取摄影机并告知其位置
//画。
试一试{
if(mCamera!=null){
mCamera.setPreviewDisplay(支架);
}
}捕获(IOException异常){
Log.e(标记“setPreviewDisplay()引起的IOException”,exception);
}
}
公共空间表面覆盖(表面覆盖物持有人){
//当我们返回时,曲面将被破坏,因此请停止预览。
/*
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera=null;
if(mCamera!=null){
mCamera.stopPreview();
}
*/
}
Camera.AutoFocusCallback mnAutoFocusCallback=新建Camera.AutoFocusCallback(){
@凌驾
自动对焦上的公共空白(布尔成功,摄像头){
}
};
公共无效表面更改(表面持有人,整数格式,整数w,整数h){
/*
if(mCamera!=null){
Camera.Parameters=mCamera.getParameters();
parameters.setPictureSize(mPreviewSize.width、mPreviewSize.height);
requestLayout();
mCamera.setParameters(参数);
mCamera.startPreview();
}
*/
}
}

我将感谢您能给我的任何帮助或指导。

您能发布错误日志吗?尽管在某些地方可能是空引用。日志中没有错误,但仍然不起作用!
SurfaceView mSurfaceView;
SurfaceHolder mHolder;
int heightmax ;
int widthmax ;
Size mPreviewSize;
List<Size> mSupportedPreviewSizes;
Camera mCamera;

@SuppressWarnings("deprecation")
Preview(Context context, SurfaceView sv) {
    super(context);

    mSurfaceView = sv;
//        addView(mSurfaceView);

    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

public void setCamera(Camera camera) {
    mCamera = camera;
    if (mCamera != null) {
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPictureSizes();
        requestLayout();

        // get Camera parameters
        Camera.Parameters params = mCamera.getParameters();

        List<String> focusModes = params.getSupportedFocusModes();
        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
            // set the focus mode
            params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            // set Camera parameters
            mCamera.setParameters(params);
        }

    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // We purposely disregard child measurements because act as a
    // wrapper to a SurfaceView that centers the camera preview instead
    // of stretching it.
    final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
    final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
    setMeasuredDimension(width, height);

    if (mSupportedPreviewSizes != null) {

      mPreviewSize=maxSize();

    }
}

public Size maxSize(){


    Size sizeMax=mSupportedPreviewSizes.get(0);

    maxsize=mSupportedPreviewSizes.get(0)
                 .height*mSupportedPreviewSizes.get(0).width;

    for(Size size:mSupportedPreviewSizes){
        if(size.height*size.width>sizeMax.width*sizeMax.height){
            sizeMax = size;

        }
    }

    return sizeMax;


}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (changed && getChildCount() > 0) {
        final View child = getChildAt(0);

        final int width = r - l;
        final int height = b - t;

        int previewWidth = width;
        int previewHeight = height;
        if (mPreviewSize != null) {
            previewWidth = mPreviewSize.width;
            previewHeight = mPreviewSize.height;
        }

        // Center the child SurfaceView within the parent.
        if (width * previewHeight > height * previewWidth) {
            final int scaledChildWidth = previewWidth * height / previewHeight;
            child.layout((width - scaledChildWidth) / 2, 0,
                    (width + scaledChildWidth) / 2, height);
        } else {
            final int scaledChildHeight = previewHeight * width / previewWidth;
            child.layout(0, (height - scaledChildHeight) / 2,
                    width, (height + scaledChildHeight) / 2);
        }
    }
}

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    try {
        if (mCamera != null) {
            mCamera.setPreviewDisplay(holder);
        }
    } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
    }
}

public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    /*
    mCamera.stopPreview();
    mCamera.setPreviewCallback(null);
    mCamera.release();
    mCamera = null;

    if (mCamera != null) {
        mCamera.stopPreview();

    }
   */
}




Camera.AutoFocusCallback mnAutoFocusCallback = new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {



    }
};
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    /*
    if(mCamera != null) {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
        requestLayout();

        mCamera.setParameters(parameters);
        mCamera.startPreview();

    }
    */
}

}