release () 예외 후에 호출 된 메서드는 Android 카메라로 다시 시작할 수 없습니다.
카메라 앱을 개발하는 동안 다른 앱 ( onPause()
내 앱용)으로 전환 할 때만 발생하는 예외가 발생했습니다 .
01-15 17:22:15.017: E/AndroidRuntime(14336): FATAL EXCEPTION: main
01-15 17:22:15.017: E/AndroidRuntime(14336): java.lang.RuntimeException: Method called after release()
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.hardware.Camera.setPreviewDisplay(Native Method)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.hardware.Camera.setPreviewDisplay(Camera.java:357)
01-15 17:22:15.017: E/AndroidRuntime(14336): at com.sora.cbir.yuki.image.leaf.CameraPreview.surfaceCreated(CameraPreview.java:32)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.SurfaceView.updateWindow(SurfaceView.java:551)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:213)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.View.dispatchWindowVisibilityChanged(View.java:4075)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:742)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:742)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:742)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:742)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.ViewRoot.performTraversals(ViewRoot.java:858)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.view.ViewRoot.handleMessage(ViewRoot.java:1995)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.os.Handler.dispatchMessage(Handler.java:99)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.os.Looper.loop(Looper.java:150)
01-15 17:22:15.017: E/AndroidRuntime(14336): at android.app.ActivityThread.main(ActivityThread.java:4389)
01-15 17:22:15.017: E/AndroidRuntime(14336): at java.lang.reflect.Method.invokeNative(Native Method)
01-15 17:22:15.017: E/AndroidRuntime(14336): at java.lang.reflect.Method.invoke(Method.java:507)
01-15 17:22:15.017: E/AndroidRuntime(14336): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
01-15 17:22:15.017: E/AndroidRuntime(14336): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
01-15 17:22:15.017: E/AndroidRuntime(14336): at dalvik.system.NativeStart.main(Native Method)
몇 가지 조사를했고 추가해야한다는 사실을 알게되었습니다.
mCamera.setPreviewCallback(null);
Android의 카메라 스택에 대한 해결 방법
내 onPause()
지금은 다음과 같습니다.
@Override
protected void onPause() {
super.onPause();
try
{
// release the camera immediately on pause event
//releaseCamera();
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
catch(Exception e)
{
e.printStackTrace();
}
}
그리고 내 onResume()
:
@Override
protected void onResume()
{
super.onResume();
try
{
mCamera.setPreviewCallback(null);
mCamera = getCameraInstance();
//mCamera.setPreviewCallback(null);
mPreview = new CameraPreview(Imageupload.this, mCamera);//set preview
preview.addView(mPreview);
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
그리고 마지막으로 내 getCameraInstance()
방법 :
public Camera getCameraInstance(){
Camera camera = null;
try {
camera = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
Camera.Parameters parameters = camera.getParameters();
//mPreviewSize = getBestPreviewSize(parameters, wt, ht);
//mPictureSize = getBestPictureSize(parameters, wt, ht);
//Shift W & H => if camera rotates 90 deg
mPreviewSize = getOptimalPreviewSize(parameters, wt, ht); //original => wt,ht
mPictureSize = getOptimalPictureSize(parameters, wt, ht); //original => wt,ht
Log.d("CAMERA", "SCREEN RESOLUTION H: "+ht);
Log.d("CAMERA", "SCREEN RESOLUTION W: "+wt);
Log.d("CAMERA", "PREVIEW RESOLUTION H: "+mPreviewSize.height);
Log.d("CAMERA", "PREVIEW RESOLUTION W: "+mPreviewSize.width);
Log.d("CAMERA", "PICTURE RESOLUTION H: "+mPictureSize.height);
Log.d("CAMERA", "PICTURE RESOLUTION W: "+mPictureSize.width);
//set preview size based on device screen
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
//set picture size based on device screen
parameters.setPictureSize(mPictureSize.width, mPictureSize.height);
//set output camera mode
parameters.setPictureFormat(PixelFormat.JPEG);
//set focous mode
parameters.setFocusMode(FOCUS_MODE_AUTO);
//set flash mode
parameters.setFlashMode("auto");
List<int[]> fps = parameters.getSupportedPreviewFpsRange();
//System.out.println("FPS size: " +fps.size());
//System.out.println("MAX FPS:"+(fps.get(fps.size()-1)[1])/1000);
//log min and max camera supported fps
Log.d("CAMERA", "CAMERA MAX FPS: "+(fps.get(fps.size()-1)[1])/1000);
Log.d("CAMERA", "CAMERA MIN FPS: "+(fps.get(fps.size()-1)[0])/1000);
if(camera_fps)
{
parameters.setPreviewFpsRange(fps.get(fps.size()-1)[1], fps.get(fps.size()-1)[1]);
}
//set camera parameters
camera.setParameters(parameters);
Toast.makeText(getApplicationContext(), "Your device are capable of previewing @" + fps.get(fps.size()-1)[1]/1000+"fps!",Toast.LENGTH_SHORT).show();
return camera; // returns null if camera is unavailable
}
이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
나도 같은 문제가 있습니다. mCamera.setPreviewCallback(null);
도움이되지 않았습니다. 내 활동에서 나는 이것을 다음에 추가했습니다 releaseCamera
.
mPreview.getHolder().removeCallback(mPreview);
이제 작동합니다.
@ ookami.kb 솔루션이 저에게도 효과가 있었고 @srunni가 댓글을 달았습니다.
public void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mPreview.getHolder().removeCallback(mPreview);
mCamera.release();
}
}
나는 onDestroy 메소드도 제거했습니다.
문서 camera.release()
는 모든 카메라 리소스 를 해제 한다고 명확하게 말합니다 . 이 통화 후에는 더 이상 카메라 참조를 사용할 수 없습니다.
카메라를 다시 사용하려면 open(int)
방법을 통해 획득해야합니다 .
카메라 문서 에 모두 설명되어 있습니다.
올바르게 재개하려면 다음을 수행해야합니다.
@Override
public void onResume() {
super.onResume();
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera initialization
}
}
protected void initializeCamera(){
// Get an instance of Camera Object
mCamera = getCameraInstance();
// create a basic camera preview class that can be included in a View layout.
mPreview=new CameraPreview(this,mCamera);
//add your preview class to the FrameLayout element.
preview.addView(mPreview);
//Trigger capturing an image by calling the Camera.takePicture() method.
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
또한 oncreate ()에서 FrameLayout 미리보기 및 Button captureButton을 정의하는 것 외에는 아무것도하지 않습니다.
@Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
this.getHolder().removeCallback(this);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
Log.e("surfaceDestroyed", "surfaceDestroyed");
}
Resume 기능에서 카메라를 다시 초기화하십시오.
okambi의 대답에 추가합니다.
재개 할 때 모든 것을 엉망으로 만드는 함수입니다.
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
try {}가 throw되는 예외를 포착하지 않습니다. 즉, mCamera가 존재하지 않고 setPreviewDisplay (holder)를 호출하려고하면 충돌이 발생합니다.
따라서 콜백을 제거하면이 surfaceCreated가 호출되지 않고 충돌을 방지합니다.
이것은 Google에서 문서화가 매우 부족합니다.
나는 넣었다
mPreview.getHolder().removeCallback(mPreview);
중에서.
mCamera.setPreviewCallback(null);
과
mCamera.release();
그리고 그것은 나를 위해 일했습니다.
@Override
protected void onPause() {
super.onPause();
this.saveTextEdits();
try {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
**mPreview.getHolder().removeCallback(mPreview);**
mCamera.release();
mCamera = null;
}catch (Exception e){
}
}
I faced same issue, i fixed it by - Adding mCamera = null; in surfaceDestroyed(SurfaceHolder holder) method of Preview class.
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
and - Adding
camera = Camera.open();
camera.startPreview();
params = camera.getParameters();
preview.setCamera(camera);
in OnResume() method of my CameraActivity.
If you got:
Attempt to invoke virtual method 'void android.hardware.Camera.setPreviewCallback(android.hardware.Camera$PreviewCallback)' on a null object reference
I agree with @ookami.kb - mCamera.setPreviewCallback(null);
is not enough, behind it also add this:
mCameraView.getHolder().removeCallback(mCameraView);
'development' 카테고리의 다른 글
% PATH %에 디렉터리가 있는지 확인하는 방법은 무엇입니까? (0) | 2020.12.06 |
---|---|
jQuery를 사용하여 하이퍼 링크 비활성화 (0) | 2020.12.06 |
양말 프록시를 통해 파이썬 요청을 작동시키는 방법 (0) | 2020.12.06 |
가장 빠르고 순수한 자바 스크립트 그래프 시각화 툴킷은 무엇입니까? (0) | 2020.12.05 |
알려진 통계 분포의 데이터 정렬 알고리즘? (0) | 2020.12.05 |