Metoda wywołana po wydaniu wyjątku podgląd kamery
Mam jedną klasę aktywności (CameraActivity), która używa mojej klasy CameraPreview. W "OnResume" kamera i podgląd są inicjowane. W "OnPause" wypuszczam zasoby aparatu. Kiedy aplikacja jest uruchomiona, wszystko działa dobrze wewnątrz "OnResume", ale kiedy rozpoczynam inną aktywność poprzez intent (np. Otwórz adres url w przeglądarce), a następnie wracam do mojej aktywności, wtedy wyjątek występuje wewnątrz" OnResume " pochodzącej klasy CamerPreview. Poniżej znajdują się kod:
//Klasa Działania Aparatu
public void onResume(){
super.onResume();
Log.d("inside onResume, camera==="+mCamera, "inside onResume");
try {
if(mCamera==null)
{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
autoFocusHandler = new Handler();
mCamera = getCameraInstance();
int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB);
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("onResume",Log.getStackTraceString(e));
}
public void onPause{
try {
super.onPause();
if (mCamera != null) {
previewing = false;
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
mPreview=null;
}
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("releaseCamera",Log.getStackTraceString(e));
}
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
} catch (Exception e){
Log.e("getCameraInstance",Log.getStackTraceString(e));
}
return c;
}
// Poniżej znajduje się Klasa CameraPreview:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
Camera mCamera;
PreviewCallback previewCallback;
AutoFocusCallback autoFocusCallback;
private int rotation;
public int getRotation() {
return rotation;
}
public void setRotation(int rotation) {
this.rotation = rotation;
}
public CameraPreview(Context context, Camera camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
super(context);
mCamera = camera;
previewCallback = previewCb;
autoFocusCallback = autoFocusCb;
/*
* Set camera to continuous focus if supported, otherwise use
* software auto-focus. Only works for API level >=9.
*/
/*
Camera.Parameters parameters = camera.getParameters();
for (String f : parameters.getSupportedFocusModes()) {
if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
autoFocusCallback = null;
break;
}
}
*/
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
if(mCamera==null){
mCamera=Camera.open();
}
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
Log.d("DBG", "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Camera preview released in activity
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
/*
* If your preview can change or rotate, take care of those events here.
* Make sure to stop the preview before resizing or reformatting it.
*/
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e){
Log.d("DBG", "Error starting camera preview: " + e.getMessage());
}
}
}
To jest z logCat:
11-05 10:14:34.585: E/AndroidRuntime(7864): FATAL EXCEPTION: main
11-05 10:14:34.585: E/AndroidRuntime(7864): java.lang.RuntimeException: Method called after release()
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.hardware.Camera.setPreviewDisplay(Native Method)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.hardware.Camera.setPreviewDisplay(Camera.java:393)
11-05 10:14:34.585: E/AndroidRuntime(7864): at com.intagleo.qraugmented.detection.camera.CameraPreview.surfaceCreated(CameraPreview.java:74)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.SurfaceView.updateWindow(SurfaceView.java:552)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:215)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.View.dispatchWindowVisibilityChanged(View.java:4027)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewRoot.performTraversals(ViewRoot.java:790)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.os.Handler.dispatchMessage(Handler.java:99)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.os.Looper.loop(Looper.java:130)
11-05 10:14:34.585: E/AndroidRuntime(7864): at android.app.ActivityThread.main(ActivityThread.java:3687)
11-05 10:14:34.585: E/AndroidRuntime(7864): at java.lang.reflect.Method.invokeNative(Native Method)
11-05 10:14:34.585: E/AndroidRuntime(7864): at java.lang.reflect.Method.invoke(Method.java:507)
11-05 10:14:34.585: E/AndroidRuntime(7864): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
11-05 10:14:34.585: E/AndroidRuntime(7864): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
11-05 10:14:34.585: E/AndroidRuntime(7864): at dalvik.system.NativeStart.main(Native Method)
EDIT
Zaktualizowałem " surfaceDestroyed "i wstawiłem logi zgodnie z sugestią, ale teraz dostaję wyjątek w" onPause " -- > onSurfaceDestroyed. Początkowo onpauza wykonywała grzywny.
1 - instancja kamery jest tworzona w "onResume" klasy activity przy pomocy metody "getCameraInstance" i przechodzi instancja mCamera do klasy CameraPreview. Próbowałem to zmienić tak, że instancja aparatu jest tworzony tylko onside "onSurfaceCreated" i przypisane z powrotem wystąpienie mCamera do klasy activity, ale to nie działa. Zauważyłem również poprzez debugowanie, że previewCallBack członek klasy" CameraPreview "jest ważny za pierwszym razem, ale za drugim razem" previewCallBack "członek klasy" CameraPreview " jest null.
Zauważ, że po pierwszym wywołaniu "onResume" wszystko działa dobrze, ale kiedy działa drugi raz po onPause wtedy wyjątek występuje pierwotnie, chociaż kod jest taki sam w onResume.
11-06 01:25:28.375: I/onResume(4332): INITIATED
// Workinf fine till now. Now opening another intent activity
11-06 01:26:23.500: I/onPause(4332): INITIATED
11-06 01:26:23.804: "OnSurfaceDestroyed": "Initiated"
11-06 01:26:23.945: E/AndroidRuntime(4332): FATAL EXCEPTION: main
11-06 01:26:23.945: E/AndroidRuntime(4332): java.lang.RuntimeException: Method called after release()
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.hardware.Camera.stopPreview(Native Method)
11-06 01:26:23.945: E/AndroidRuntime(4332): at com.intagleo.qraugmented.detection.camera.CameraPreview.surfaceDestroyed(CameraPreview.java:85)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:596)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.SurfaceView.updateWindow(SurfaceView.java:490)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:215)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.View.dispatchWindowVisibilityChanged(View.java:4027)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewRoot.performTraversals(ViewRoot.java:790)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.os.Handler.dispatchMessage(Handler.java:99)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.os.Looper.loop(Looper.java:130)
11-06 01:26:23.945: E/AndroidRuntime(4332): at android.app.ActivityThread.main(ActivityThread.java:3687)
11-06 01:26:23.945: E/AndroidRuntime(4332): at java.lang.reflect.Method.invokeNative(Native Method)
11-06 01:26:23.945: E/AndroidRuntime(4332): at java.lang.reflect.Method.invoke(Method.java:507)
11-06 01:26:23.945: E/AndroidRuntime(4332): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
11-06 01:26:23.945: E/AndroidRuntime(4332): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
11-06 01:26:23.945: E/AndroidRuntime(4332): at dalvik.system.NativeStart.main(Native Method)
7 answers
Jak dodałeś aparat do FrameLayout, tak:
FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview);
preview.addView(mPreview);
Metoda surfaceCreated
zostanie wywołana, a więc mCamera.setPreviewDisplay(holder);
zostanie wywołana.
Kiedy utworzysz / otworzysz nową kamerę, FrameLayout
nadal ma Twoją poprzednią kamerę, więc jej surfaceCreated
zostanie wywołana jako dodatek do nowej kamery.
Należy wyjąć poprzedni Aparat z FrameLayout
Po zwolnieniu aparatu (w metodzie onPause()
) w następujący sposób:
preview.removeView(mPreview);
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-19 11:20:26
Dan ma rację. Zobacz też Tutaj .
Próbka kodu:
public class MainActivity extends Activity {
private FrameLayout mFlCameraPreview;
private Camera mCamera;
private CameraPreview mCameraPreview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFlCameraPreview = (FrameLayout) findViewById(R.id.main_fl_camera_preview);
}
@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
mCamera = getCameraInstance();
}
if (mCameraPreview == null) {
mCameraPreview = new CameraPreview(this, mCamera);
mFlCameraPreview.addView(mCameraPreview);
}
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if (mCameraPreview != null) {
mFlCameraPreview.removeView(mCameraPreview);
mCameraPreview = null;
}
}
public static Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
}
return camera;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:25
EDIT
Nie mogę być w 100% pewien, co powoduje twoje wyjątki. Poniżej umieściłem Mój kod aparatu, mam nadzieję, że pomoże, używam metodstartCamera()
i stopCamera()
, które wywołuję w onPause
i onResume
. Ja również, tylko utworzyć nową instancję klasy CameraPreview
w moim onCreate
, nie re-instantiate w onResume
chyba że mój cameraView == null
. Jest kilka rzeczy, które robimy inaczej. Mam nadzieję, że poniższy kod pomoże, Może można grać z nim, aby uzyskać swój praca:
P. S.: u mnie Wszystko działa. tj. wchodzenie w inne zajęcia itp. Jedyną częścią cyklu życia, której nie testowałem, jest onDestroy
, ale to dlatego, że moja aplikacja jest zaprojektowana tak, aby zaczynała się od początku w tym cyklu.
Główna aktywność:
boolean cameraReleased = false;
@Override
protected void onPause() {
Log.i("onPause", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == false) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.stopCamera();
cameraReleased = true;
}
if (cameraView == null) {
Log.i("onPause", "cameraView == null");
cameraView = new JJCameraSurfaceView(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onPause();
}
@Override
protected void onDestroy() {
Log.e("onDestroy", "INITIATED");
super.onDestroy();
}
@Override
protected void onResume() {
Log.i("onResume", "CALLED:: cameraReleased = " + cameraReleased);
Log.i("onResume", "CALLED:: cameraView = " + cameraView.toString());
if (cameraReleased == true) {
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
}
if (cameraView == null) {
Log.i("onResume", "cameraView == null");
cameraView = new JJCameraPreview(getApplicationContext());
imageResult = new ImageView(getApplicationContext());
}
super.onResume();
}
@Override
public void onBackPressed() {
// If Statement used to get out of my camera view and back to my MainActivity - Same Class
if (“Camera Preview or Image Result is displayed”) {
cameraView.stopCamera();
image = null;
imageResult.setImageBitmap(null);
imageResult.setImageResource(0);
cameraView.startCamera();
return;
}
Log.i("onBackPressed", "WAS PRESSED");
super.onBackPressed();
}
CameraPreview:
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.w("surfaceChanged", "STARTED");
if (camera != null) {
Log.w("surfaceChanged", "camera = NOT NULL");
Camera.Parameters cParams = camera.getParameters();
cParams.setPreviewSize(width, height);
cParams.setSceneMode(Parameters.SCENE_MODE_NIGHT);
camera.setParameters(cParams);
camera.startPreview();
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.w("surfaceCreated", "STARTED");
if (camera == null) {
camera = Camera.open();
}
try {
camera.setPreviewDisplay(mHolder);
} catch (Exception e) {
Log.e("setPreviewDisplay", "FAILED: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.w("CameraSurfaceDestroyed", "INITIATED");
camera.stopPreview();
camera.release();
camera = null;
}
public void startCamera() {
Log.w("startCamera", "CALLED");
mHolder = getHolder();
surfaceCreated(mHolder);
camera.startPreview();
mHolder.addCallback(this);
}
public void stopCamera() {
mHolder = getHolder();
mHolder.removeCallback(this);
camera.stopPreview();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-07 13:25:11
Miałem podobny problem z moim kodem, który był wymuszonym zamknięciem z błędem Method called after release()
.
Wywoływałem metodę SetupCamera()
w OnResume()
, która sprawdzała, czy obiekt jest null camera
, a następnie wywoływała camera.Open()
.
Naprawiono mój problem polegający na pozbyciu się null-check i wywołaniu camera.Open()
czy to było null, czy nie (już ustawiłem camera = null
na onPause
) po przeczytaniu Camera Docs.
Wiem, że nie jest to definitywne w śledzeniu mojego problemu, ale to absolutnie zadziałało na ja!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-28 04:19:35
Moje rozwiązanie robocze:
Pierwszy:
W {[3] } class declare mCamera
as array:
Camera mCamera[] = new Camera[1];
Po Drugie: deklaracja konstruktora CameraPreview
musi wyglądać tak:
public CameraPreview(Context context, Camera[] camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
mCamera = camera;
...
}
Ale mCamera
w CameraPreview
klasa musi być zadeklarowana w następujący sposób:
Camera[] mCamera; // without instantiating of the array!
I na koniec: w obu klasach wewnątrz wszystkich metod należy zastąpić wszystkie odwołania mCamera
przez mCamera[0]
P. s: Sorry for my English
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-10 03:21:36
Spróbuj użyć poniższego kodu, zamiast nadpisywania onpause() i onResume(), nadpisuje OnStop() i onRestart(). W cyklu życia aktywności wywoływana jest metoda onStop (), gdy aktywność nie jest widoczna, a następnym wywołaniem metody cyklu życia jest metoda onRestart (). Spójrz na poniższy kod.
@Override
protected void onStop() {
super.onStop();
try {
m_camera.stopPreview();
m_camera.release();
preview.removeView(m_CameraPreview);
/*
m_CameraPreview is the object of the class that looks like this : public class CameraSurfaceView extends SurfaceView implements Callback
*/
}
catch(Exception e)
{
e.printStackTrace();
}
}
@Override
protected void onRestart() {
super.onRestart();
m_camera=getCameraInstance();//Initialize the camera in your own way
m_CameraPreview = new CameraSurfaceView(this, m_camera);
preview = (FrameLayout)findViewById(R.id.camera_preview);
preview.addView(this.m_CameraPreview);
/*
*camera_preview is the id of the framelayout defined in xml file and preview is *the instance of FrameLayout.
*/
}
Jak powiedział Dan, układ ramki będzie miał miejsce w stosunku do poprzedniej instancji kamery, a jego wywołania zwrotne "surfaceview" zostaną utworzone oprócz nowych obiektów tworzących stan rasy. Stąd trzeba by go zwolnić w OnStop () i ponownie uruchomić w onrestart (). Mam nadzieję, że to pomoże.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-21 12:50:38
Miałem ten sam błąd. Poniżej Sekwencja rozwiązuje mój problem.
Call getHolder().removeCallback(this);
in surfaceDestroyed()
Call
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
if(mPreview != null){
mPreview.destroyDrawingCache();
mPreview.mCamera = null;
}
}
W onPause
Call
private boolean safeCameraOpenInView(View view) {
boolean qOpened = false;
releaseCameraAndPreview();
mCamera = getCameraInstance();
mCameraView = view;
qOpened = (mCamera != null);
if(qOpened == true){
mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera,view);
preview = (FrameLayout) view.findViewById(R.id.camera_preview);
preview.addView(mPreview);
mPreview.startCameraPreview();
}
return qOpened;
}
W onCreateView()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-03 06:12:24