如何在android中的相机surfaceview上解决在release()异常后调用的方法

时间:2014-10-09 04:40:05

标签: android camera surfaceview

我正在开发一个应用程序,因为我想用后置和前置摄像头显示摄像头surfaceview。在那个开关相机工作但捕获图像然后它将引发释放异常后调用的方法。我怎么能解决这个问题,请有人告诉我.....

logcat的:

10-09 10:32:33.530: E/AndroidRuntime(8915): FATAL EXCEPTION: main
10-09 10:32:33.530: E/AndroidRuntime(8915): java.lang.RuntimeException: Method called after    release()
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.hardware.Camera.native_takePicture(Native Method)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.hardware.Camera.takePicture(Camera.java:1095)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.hardware.Camera.takePicture(Camera.java:1040)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at com.example.cameraview.CamTestActivity$4.onClick(CamTestActivity.java:124)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.view.View.performClick(View.java:4207)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.view.View$PerformClick.run(View.java:17372)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.os.Handler.handleCallback(Handler.java:725)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.os.Handler.dispatchMessage(Handler.java:92)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.os.Looper.loop(Looper.java:137)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at android.app.ActivityThread.main(ActivityThread.java:5041)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at java.lang.reflect.Method.invokeNative(Native Method)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at java.lang.reflect.Method.invoke(Method.java:511)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-09 10:32:33.530: E/AndroidRuntime(8915):     at dalvik.system.NativeStart.main(Native Method)

camera.java:

public class CamTestActivity extends Activity implements CameraCallback {
private static final String TAG = "CamTestActivity";
Preview preview;
Button buttonClick,front,zoomin,zoomout,tattooselect;
Camera camera;
Activity act;
Context ctx;
ImageView imm,aboveimg;
LayoutInflater controlInflater ;
Camera.Parameters params;
public RelativeLayout layout,rlayout;
Bitmap bitmap=null;
SurfaceHolder surfaceholder;
int myScreenHeight = 0;
int myScreenWidth = 0;
Bitmap bitmapPicture;
@SuppressLint("InlinedApi")
boolean previewing = false;
@SuppressLint("InlinedApi")
public static int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
int numberOfCamera;
private int[] tattoos;
GridView gview;
Bitmap backimage;
public static File outFile;
int screenWidth, screenHeight;
public static String fileName;
int position;
int cameraID;
boolean isFrontCamera=false;
View v;

@SuppressLint({ "NewApi", "ShowToast" })
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ctx = this;
    act = this;

    setContentView(R.layout.main);

    layout=(RelativeLayout)findViewById(R.id.relative);
    rlayout=(RelativeLayout)findViewById(R.id.rrlayout);
    preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView));
    preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

    imm=(ImageView)findViewById(R.id.imageView1);
    aboveimg=(ImageView)findViewById(R.id.imageView2);
    rlayout.addView(preview);
    aboveimg.setOnTouchListener(new Touchhimage());

    Toast.makeText(getApplicationContext(), "" +camId,Toast.LENGTH_LONG).show();
    preview.setKeepScreenOn(true);

    buttonClick = (Button)findViewById(R.id.btnCapture);
    //buttonClick.setPressed(true);
    zoomin=(Button)findViewById(R.id.button3);

    zoomout=(Button)findViewById(R.id.button2);

    front=(Button)findViewById(R.id.button1);
    gview=(GridView)findViewById(R.id.gridview);

    tattooselect=(Button)findViewById(R.id.button4);


    //setCameraDisplayOrientation(CamTestActivity.this, currentCameraId, camera);


    buttonClick.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            //preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);

            camera.takePicture(shutterCallback, rawCallback, jpegCallback);

        }
    });


    zoomin.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            preview.zoom();
        }
    });

    zoomout.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            preview.unzoom();
        }
    });
    if(Camera.getNumberOfCameras() == 1){
        front.setVisibility(View.INVISIBLE);
    }
    else {

        front.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                preview.openFrontFacingCamera();


            }

        });

    }


    tattooselect.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub

            gview.setAdapter(new GridAdapter(getApplicationContext())); 
            gview.setVisibility(View.VISIBLE);
        }
    });


    gview.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View view, int position,
                long arg3) {
            // TODO Auto-generated method stub
            Toast.makeText(getApplicationContext(), "visible", 1000).show();
            backimage= BitmapFactory.decodeResource(getResources(), tattoos[position]);

            scaling(backimage);

            aboveimg.setVisibility(View.VISIBLE);

            aboveimg.setImageBitmap(Utils.camerabitmap);
            gview.setVisibility(View.INVISIBLE);
        }
      });


     }


    public void scaling(Bitmap backimage)
    {

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    //   BitmapFactory.decodeStream(in, null, options);
    ///  in.close();
    //  in = null;

    // save width and height
    //  inWidth = options.outWidth;
    //  inHeight = options.outHeight;

    // decode full image pre-resized
    //  in = new FileInputStream(imageFile.getAbsolutePath());
    options = new BitmapFactory.Options();
    // calc rought re-size (this is no exact resize)
    //options.inSampleSize = Math.max(inWidth/screenWidth, inHeight/screenHeight);
    // decode full image
    // Bitmap roughBitmap = BitmapFactory.decodeStream(in, null, options);

    // calc exact destination size
    Matrix m = new Matrix();
    RectF inRect = new RectF(0, 0, backimage.getWidth(), backimage.getHeight());
    RectF outRect = new RectF(0, 0, screenWidth, screenHeight);
    m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER);
    float[] values = new float[9];
    m.getValues(values);

    // resize bitmap
    Utils.camerabitmap = Bitmap.createScaledBitmap(backimage, imm.getWidth(), imm.getHeight(), true);

      }



     @SuppressLint("NewApi") @Override
      protected void onResume() {
     super.onResume();

     //camera.setPreviewCallback(null);
     camera = Camera.open(camId);

    // camera.startPreview();

    preview.setCamera(camera);
    }

     @Override
     protected void onPause() {
     if(camera != null) {

        //camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera=null;

    }
    super.onPause();
    }

   /*public void initializecamera()
   {

    preview = new Preview(this, (SurfaceView)findViewById(R.id.surfaceView));
    preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

    rlayout.addView(preview);


    buttonClick.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            //preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback);

            camera.takePicture(shutterCallback, rawCallback, jpegCallback);

        }
        });

    }*/
     @SuppressLint("NewApi")
     private void resetCam() {
    imm.setVisibility(View.INVISIBLE);

    camera.startPreview();
    preview.setCamera(camera);
   }

    private void refreshGallery(File file) {
    Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    mediaScanIntent.setData(Uri.fromFile(file));
    sendBroadcast(mediaScanIntent);
   }

     ShutterCallback shutterCallback = new ShutterCallback() {
    public void onShutter() {
        //Log.d(TAG, "onShutter'd");
    }
   };

     PictureCallback rawCallback = new PictureCallback() {
      public void onPictureTaken(byte[] data, Camera camera) {

        //Log.d(TAG, "onPictureTaken - raw");
    }
  };

  PictureCallback jpegCallback = new PictureCallback() {
    @SuppressLint({ "NewApi", "DefaultLocale" })

    public void onPictureTaken(byte[] data, Camera camera) {
        //dataaa=data;

        //  new SaveImageTask().execute(data);
        bitmapPicture = BitmapFactory.decodeByteArray(data, 0, data.length);
        //setCameraDisplayOrientation(CamTestActivity.this, camId, camera);

        imm.setImageBitmap(bitmapPicture);
        imm.setVisibility(View.VISIBLE);
        //resetCam();
        FileOutputStream outStream = null;
        layout.getRootView();
        layout.setDrawingCacheEnabled(true);
        layout.buildDrawingCache();
        Bitmap m=layout.getDrawingCache();

        // Write to SD Card
        try {

            File sdCard = Environment.getExternalStorageDirectory();
            File dir = new File (sdCard.getAbsolutePath() + "/camtest");
            dir.mkdirs();           
            fileName = String.format("%d.jpg", System.currentTimeMillis());
            outFile = new File(dir, fileName);
            outStream = new FileOutputStream(outFile);
            m.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
            outStream.write(data[0]);
            outStream.flush();
            outStream.close();

            Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());
            refreshGallery(outFile);
        }

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

        Intent i=new Intent(CamTestActivity.this,Imageshare.class);
        i.putExtra("imagepath", outFile.getAbsolutePath());
        startActivity(i);
        resetCam();

        Log.d(TAG, "onPictureTaken - jpeg");
      }
      };

surfaceview.java:

 class Preview extends ViewGroup implements SurfaceHolder.Callback {
 protected static final String camera = null;
 Camera.Parameters params;
 private final String TAG = "Preview";
 protected Camera.Size mPictureSize;
 protected Activity mActivity;
 SurfaceView mSurfaceView;
 SurfaceHolder mHolder;
 Size mPreviewSize;
 List<Size> mSupportedPreviewSizes;
 Camera mCamera;
 Context context;
 int currentZoomLevel ;
 int maxZoomLevel ;
 boolean previewing = false;
 @SuppressLint("InlinedApi")
 int camId;
 int  noofcameras;
 public static  CameraInfo info;
 // private CameraCallback callback = null;
 List<Camera.Size> previewSizes;
 private CameraCallback callback = null;
 int cameraID;
 public boolean cameraConfigured=false;
 private static final int PICTURE_SIZE_MAX_WIDTH = 1280;
 private static final int PREVIEW_SIZE_MAX_WIDTH = 640;




 //private TutorialThread _thread;
 @SuppressLint("NewApi")
  @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);
    //params = mCamera.getParameters();

   }

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

        // get 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 = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
     }
     }

   @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);
        }
        }
        } 


        @SuppressLint({ "WrongCall", "NewApi" })
      public void surfaceCreated(final SurfaceHolder holder) {
     // The Surface has been created, acquire the camera and tell it where
     // to draw.
     /*
     determineDisplayOrientation();
     setupCamera();*/
     /*try {
        if (mCamera != null) {
            // mCamera = Camera.open(camId);            
            mCamera.setPreviewDisplay(holder);
            //mCamera.startPreview();
            //mCamera=Camera.open(camId);
            params = mCamera.getParameters();
            params.set("orientation", "portrait");
            params.setRotation(90);
            mCamera.setDisplayOrientation(90);

            mCamera.setParameters(params);
            mCamera.startPreview();


        }
     } catch (IOException exception) {
        Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
     }*/

     camId=findCameraID();
     noofcameras = Camera.getNumberOfCameras();
     info = new CameraInfo(); 
     Camera.getCameraInfo(camId, info);

     if(mCamera==null){

     mCamera = Camera.open(camId);

        //safeCameraOpen(camId);

          }

            // camera = Camera.open();

             try {
                     mCamera.setPreviewDisplay(holder);
                     mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                             @Override
                             public void onPreviewFrame(byte[] data, Camera camera) {
                                     if(null != callback) callback.onPreviewFrame(data, camera);
                             }

                     });

                    params = mCamera.getParameters();
                    params.set("orientation", "portrait");
                    params.setRotation(90);
                    mCamera.setDisplayOrientation(90);

                    mCamera.setParameters(params);


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

        @SuppressLint({ "NewApi", "ShowToast" })
       public void openFrontFacingCamera() {
       noofcameras = Camera.getNumberOfCameras();

      if(camId == Camera.CameraInfo.CAMERA_FACING_BACK){

        camId = Camera.CameraInfo.CAMERA_FACING_FRONT;

        try {

            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera=null;
            mCamera = Camera.open(camId);
            //onOrientationChanged(0);
            mCamera.setPreviewDisplay(mHolder);
            mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                            if(null != callback) callback.onPreviewFrame(data, camera);
                    }
            });
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();


            //previewing = true;
          } catch (RuntimeException e) {

          }catch (IOException e) {}
         }else if(camId == Camera.CameraInfo.CAMERA_FACING_FRONT){
         camId = Camera.CameraInfo.CAMERA_FACING_BACK;


         try {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera=null;
            mCamera=Camera.open(camId);
            mCamera.setPreviewDisplay(mHolder);
            mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                            if(null != callback) callback.onPreviewFrame(data, camera);
                    }
            });
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();


        } catch (RuntimeException e) {

        }catch (IOException e) {}
      }
      }
      @SuppressLint("NewApi")
       private int findCameraID() {
      // TODO Auto-generated method stub
        int foundId = -1;
        int numCams = Camera.getNumberOfCameras();
        System.out.println("no of cameras are "+numCams);
        for (int camId = 0; camId < numCams; camId++) {
            CameraInfo info = new CameraInfo(); 
            Camera.getCameraInfo(camId, info); 
            if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
                foundId = camId;
                break;
            }else 
            if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                foundId = camId;
                break;
            }
          }
          return foundId;
            }

    public void zoom()
     {

        params=mCamera.getParameters();
        maxZoomLevel = params.getMaxZoom();
        if (currentZoomLevel < maxZoomLevel) {
         currentZoomLevel++;
         params.setZoom(currentZoomLevel);
         mCamera.setParameters(params);

      }

     }

    public void unzoom()
    {
        params=mCamera.getParameters();
        maxZoomLevel = params.getMaxZoom();
        if (currentZoomLevel > 0) {
         currentZoomLevel--;
         params.setZoom(currentZoomLevel);
         mCamera.setParameters(params);
     }

    }


     public void surfaceDestroyed(SurfaceHolder holder) {
      // Surface will be destroyed when we return, so stop the preview.


      if (mCamera != null) {

        //mCamera.stopPreview();

        mCamera.stopPreview();
        mCamera.setPreviewCallback(null);
        mCamera.release();
        mCamera = null;
        previewing = false;
        }
        }


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

     Size optimalSize = null;
     double minDiff = Double.MAX_VALUE;
     int targetHeight = h;

     // Try to find an size match aspect ratio and size
     for (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);
        }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement 
          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);
            }
          }
          }
      return optimalSize;
     }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {


     if(mCamera != null) {

        params=mCamera.getParameters();
        params.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        mCamera.setParameters(params);
        requestLayout();
        mCamera.setDisplayOrientation(90);
        mCamera.startPreview();

        }

0 个答案:

没有答案