2011-07-28 4 views
9

J'ai rencontré des problèmes similaires à ceux que j'ai rencontrés, mais je n'arrive toujours pas à trouver une solution. Je suis très nouveau dans le développement Android, donc j'ai du mal à trouver mon problème. Quoi qu'il en soit, j'essaie de créer un aperçu de la caméra en utilisant une classe CameraSurfaceView que j'ai créée qui étend SurfaceView et implémente SurfaceHolder.Callback. Peu importe ce que j'essaie dans ma classe StartCamera, la méthode surfaceCreated() n'est jamais appelée, donc ma caméra ne démarre jamais. Toute aide serait géniale, merci!surfaceCreated() Jamais appelé

StartCamera.java

import net.peterd.zombierun.R; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.widget.FrameLayout; 

public class StartCamera extends BaseActivity { 

    private Camera mCamera; 
    private CameraSurfaceView mView; 

    public void onCreate(Bundle state) { 
     // TODO Auto-generated constructor stub 
     super.onCreate(state); 
     setContentView(R.layout.start_camera); 
    } 

    public void onResume() { 
     super.onResume(); 

     mView = new CameraSurfaceView(this); 
     FrameLayout preview = (FrameLayout) findViewById(R.id.cPreview); 
     preview.addView(mView); 
    } 

    public void onPause() { 
     mCamera.stopPreview(); 
     mCamera.release(); 
    } 

} 

CameraSurfaceView.java

import java.io.IOException; 
import android.content.Context; 
import android.hardware.Camera; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback 
{ 
     private SurfaceHolder holder; 
     private Camera camera; 

     public CameraSurfaceView(Context context) 
     { 
       super(context); 

       //Initiate the Surface Holder properly 
       this.holder = this.getHolder(); 
       this.holder.addCallback(this); 
       this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     } 

     @Override 
     public void surfaceCreated(SurfaceHolder holder) 
     { 
       try 
       { 
         //Open the Camera in preview mode 
         this.camera = Camera.open(); 
         this.camera.setPreviewDisplay(this.holder); 
       } 
       catch(IOException ioe) 
       { 
         ioe.printStackTrace(System.out); 
       } 
     } 

     @Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
     { 
       // Now that the size is known, set up the camera parameters and begin 
       // the preview. 
       Camera.Parameters parameters = camera.getParameters(); 
       parameters.setPreviewSize(width, height); 
       camera.setParameters(parameters); 
       camera.startPreview(); 
     } 

     @Override 
     public void surfaceDestroyed(SurfaceHolder holder) 
     { 
       // Surface will be destroyed when replaced with a new screen 
       //Always make sure to release the Camera instance 
       camera.stopPreview(); 
       camera.release(); 
       camera = null; 
     } 

     public Camera getCamera() { 
      return camera; 
     } 
} 

start_camera.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <FrameLayout android:id="@+id/cPreview" 
     android:layout_weight="1" android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 
    </FrameLayout> 

</LinearLayout> 

Répondre

6

Apparemment, cela est dû à FrameLayout être vide et donc ne pas créer une sorte de SurfaceView . Vous pouvez essayer de forcer manuellement la hauteur et la largeur du paramètre LinearLayout parent ou simplement ajouter un imageView dans le FrameLayout. Depuis FrameLayout peut contenir de nombreux widgets, mais il ne montre que le dernier d'entre eux, vous pouvez mettre un ImageView dans le FrameLayout montrant une petite image seulement pour le SurfaceView à créer.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" android:layout_width="fill_parent" 
android:layout_height="fill_parent"> 

<FrameLayout android:id="@+id/cPreview" 
    android:layout_weight="1" android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

<!-- Adding small dummy image --> 
<ImageView android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    src="@drawable/small_picture"> 

</FrameLayout> 

</LinearLayout> 
+1

J'ai le même problème. Quelqu'un peut-il résoudre cela? –

0

J'ai eu des erreurs de cette ligne dans la méthode CameraSurfaceView, surfaceChanged:

camera.setParameters(parameters); 

Il a bien fonctionné une fois que je commentais cela.

1

@jvnane J'ai essayé votre code, ça marche, avec un bug mineur.

surfaceChanged est appelée sans problème. De quelle manière tu penses que ça ne marche pas? Essayez d'ajouter un message de débogage et de voir dans LogCat:

@Override 
public void surfaceCreated(final SurfaceHolder holder) 
{ 
    Log.i("Camera Test", "It works!"); 
    try 
    { 
     //Open the Camera in preview mode 
     this.camera = Camera.open(); 
     this.camera.setPreviewDisplay(this.holder); 
    } 
    catch(final IOException ioe) 
    { 
     ioe.printStackTrace(System.out); 
    } 
} 

bug mineur: objet Camera est sorti en surfaceDestroyed de sorte que vous n'avez pas besoin de le libérer à nouveau dans de l'activité. En outre, vous devez appeler super.onPause() en remplaçant la méthode onPause().

5

J'ai eu le même problème. Pour moi, c'était parce que la taille de la vue était mise à 0, et donc la surface n'a jamais été créée. J'ai vérifié cela en définissant une taille spécifique, et tout à coup les rappels ont été appelés. (Idem, apparemment, est valable si la vue est affichée hors écran).