En développant une application caméra, j'ai rencontré une exception qui se produisait uniquement lorsque je passais à une autre application (onPause()
pour mon application).
01-15 17:22:15.017: E/AndroidRuntime(14336): FATAL EXCEPTION: main
01-15 17:22:15.017: E/AndroidRuntime(14336): java.lang.RuntimeException: Méthode appelée après la libération()
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)
J'ai fait des recherches et j'ai découvert que je devais ajouter
mCamera.setPreviewCallback(null);
comme solution de contournement pour la pile caméra Android
Maintenant, mon onPause()
ressemble à ceci :
@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();
}
}
et mon 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, "Erreur lors du démarrage de l'aperçu de la caméra: " + e.getMessage());
}
}
}
et enfin ma méthode getCameraInstance()
:
public Camera getCameraInstance(){
Camera camera = null;
try {
camera = Camera.open(); // tentative pour obtenir une instance de la caméra
}
catch (Exception e){
// La caméra n'est pas disponible (utilisée ou n'existe pas)
}
Camera.Parameters parameters = camera.getParameters();
//mPreviewSize = getBestPreviewSize(parameters, wt, ht);
//mPictureSize = getBestPictureSize(parameters, wt, ht);
//Décalage W & H => si la caméra tourne de 90 degrés
mPreviewSize = getOptimalPreviewSize(parameters, wt, ht); //original => wt,ht
mPictureSize = getOptimalPictureSize(parameters, wt, ht); //original => wt,ht
Log.d("CAMERA", "RÉSOLUTION DE L'ÉCRAN H: "+ht);
Log.d("CAMERA", "RÉSOLUTION DE L'ÉCRAN W: "+wt);
Log.d("CAMERA", "RÉSOLUTION DE L'APERÇU H: "+mPreviewSize.height);
Log.d("CAMERA", "RÉSOLUTION DE L'APERÇU W: "+mPreviewSize.width);
Log.d("CAMERA", "RÉSOLUTION DE L'IMAGE H: "+mPictureSize.height);
Log.d("CAMERA", "RÉSOLUTION DE L'IMAGE W: "+mPictureSize.width);
//définir la taille de l'aperçu en fonction de l'écran de l'appareil
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
//définir la taille de l'image en fonction de l'écran de l'appareil
parameters.setPictureSize(mPictureSize.width, mPictureSize.height);
//définir le mode de sortie de la caméra
parameters.setPictureFormat(PixelFormat.JPEG);
//définir le mode de mise au point
parameters.setFocusMode(FOCUS_MODE_AUTO);
//définir le mode flash
parameters.setFlashMode("auto");
List fps = parameters.getSupportedPreviewFpsRange();
//System.out.println("FPS size: " +fps.size());
//System.out.println("MAX FPS:"+(fps.get(fps.size()-1)[1])/1000);
//journal des fps min et max pris en charge par la caméra
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]);
}
//définir les paramètres de la caméra
camera.setParameters(parameters);
Toast.makeText(getApplicationContext(), "Votre appareil est capable de prévisualiser @" + fps.get(fps.size()-1)[1]/1000+"fps!",Toast.LENGTH_SHORT).show();
return camera; // retourne null si la caméra n'est pas disponible
}
Des idées sur comment résoudre cela?