我正在开发一个应用程序,因为我想用后置和前置摄像头显示摄像头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();
}