我知道有一些类似的主题与此相关,但我无法解决我的问题。无论如何,我正在尝试使用" flash"制作一些前置摄像头。在Camera.release
时,我在整个活动中只调用surfaceDestroyed()
一次。所以这是我的MainActivity:
@SuppressWarnings("deprecation")
public class MainActivity extends AppCompatActivity {
private Camera mCamera = null;
private CameraPreview mCameraView = null;
private int cameraId = 0;
private void addView() {
if (!getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
.show();
} else {
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
Toast.makeText(this, "No front facing camera found.",
Toast.LENGTH_LONG).show();
} else {
try {
mCamera = Camera.open(cameraId);
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
}
}
if (mCamera != null) {
mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addView();
ImageButton imgCapture = (ImageButton) findViewById(R.id.imgCapture);
imgCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
WindowManager.LayoutParams layout = getWindow().getAttributes();
layout.screenBrightness = 1F;
getWindow().setAttributes(layout);
setContentView(R.layout.whitescreen);
new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
if (CameraPreview.safeToTakePicture) {
CameraPreview.safeToTakePicture = false;
mCamera.takePicture(null, null,
new PhotoHandler(getApplicationContext()));
}
setContentView(R.layout.activity_main);
addView();
}
}.start();
}
});
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
Log.d("Camera", "Camera found");
cameraId = i;
break;
}
}
return cameraId;
}
}
按下拍摄按钮时,我将布局切换为空白布局(白色布局),等待3秒钟拍照,然后再次添加相机视图,这是我的CameraPreview类:
@SuppressWarnings("deprecation")
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public static boolean safeToTakePicture = false;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
if (mHolder.getSurface() == null)
return;
try {
mCamera.stopPreview();
} catch (Exception e) {
Log.d("ERROR", "Trying the camera and it's not running");
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
safeToTakePicture = true;
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}
}
我多次收到错误Camera is being used after Camera.release was called
,例如在拍照时:
07-02 14:49:35.561 19017-19017/davidandguy.com.selfielightcamera E/AndroidRuntime: FATAL EXCEPTION: main
Process: davidandguy.com.selfielightcamera, PID: 19017
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1523)
at android.hardware.Camera.takePicture(Camera.java:1468)
at davidandguy.com.selfielightcamera.MainActivity$1$1.onFinish(MainActivity.java:65)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
或者甚至在调用onResume()
时,例如,最小化活动然后再次运行。我知道我需要放置onPause()
和onResume()
,但我不知道在哪里/如何实现它。谢谢
答案 0 :(得分:0)
这真的是过期的,但是当我在一分钟前设法解决了我的类似问题时,我想我会为自己和其他任何可能拼命搜索Stack的人做出贡献。
我在这里看不到你的生命周期代码,但是对我有用的是,在我的情况下,surfaceDestroyed是空的
首先是cameraPreview
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
try {
this.mCamera.setPreviewDisplay(surfaceHolder);
this.mCamera.startPreview();
} catch (Exception e) {
}
}
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
//TODO we need this here too because on SurfaceCreated we always need to open the camera, in case its released
this.mCamera.setPreviewDisplay(surfaceHolder);
this.mCamera.setDisplayOrientation(90);
//this.mCamera.startPreview();
} catch (IOException e) {
}
}
接下来是CameraActivity
@Override
public void onResume() {
super.onResume();
try{
mCamera = openFrontFacingCameraGingerbread();
// Add to Framelayout
this.mCameraPreview = new CameraPreview(this, this.mCamera);
mImage.removeAllViews();
this.mImage.addView(this.mCameraPreview);
}catch (RuntimeException ex){
}
}
@Override
public void onPause() {
super.onPause();
captureButton.setText("Begin Capture");
if(CameraActivity.this.timer !=null) {
CameraActivity.this.timer.cancel();
CameraActivity.this.timer.purge();
CameraActivity.this.timer = null;
}
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCameraPreview.getHolder().removeCallback(mCameraPreview);
mCamera.release();
mCamera = null;
}
}
@Override
protected void onDestroy(){
super.onDestroy();
releaseCameraAndPreview();
}
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if(mCameraPreview != null){
mCameraPreview.destroyDrawingCache();
mCameraPreview.mCamera = null;
}
}