2013-01-07 8 views
5

Utilizzo l'API della fotocamera per scrivere un'app: mostra l'anteprima e scatta una foto. La prima versione funziona molto bene. In Anteprima classe estende SurfaceView implementa SurfaceHolder.CallbackL'app dell'API per videocamera Android si blocca su onResume

public void surfaceCreated(SurfaceHolder holder) { 
    // The Surface has been created, acquire the camera and tell it where 
    // to draw. 
    camera = Camera.open(); 
    try { 
     camera.setPreviewDisplay(holder); 
     camera.startPreview(); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    hasSurface = true; 
} 


public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    // It will be called immediately after surfaceCreated 
    // I move it to Resume. 
    setCameraPreviewParameters(); 

    camera.startPreview(); 

} 

Nell'attività principale:

public class CameraDemo extends Activity 

Ho anche impostare un membro: CameraUnit ui; È:

public class CameraUnit extends LinearLayout 

Nel onCreate,

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ui = new CameraUnit(this); 
    setContentView((View) ui); 

    Log.d(TAG, "onCreate'd"); 
} 

si crea un oggetto LinearLayout, che contiene il SurfaceView, e un pulsante della fotocamera.

L'onResume è:

@Override 
protected void onResume() { 
    super.onResume(); 
} 

Anche se funziona, penso che l'onResume non dovrebbe essere vuoto. Vedo anche che surfaceCreated e surfaceChanged sono vuoti in un famous Android app example OCRTest Quindi credo sia meglio e anche possibile spostare i comandi in surfaceCreated e surfaceChanged su onResume.

penso che la chat di flusso per la prima versione della mia applicazione dovrebbe essere: Attività principale onCreate (dove il LinearLayout e la sua SurfaceView, vengono creati pulsante della fotocamera), surfaceCreated e surfaceChanged sono chiamati, onResume.

Quindi posso semplicemente spostare i comandi in surfaceCreated e surfaceChanged su onResume. Ma non funziona! Ho usato Debug per scoprire che la superficie è nulla. Penso che SurfaceCreatd non venga chiamato. La mia app è diversa da OCRTest, che implementa SurfaceHolder.Callback nell'attività principale. A implementare SurfaceHolder.Callback nel SurfaceView:

class Preview extends SurfaceView implements SurfaceHolder.Callback 

Quindi aggiungo altre due linee in onResume

 ui.preview.surfaceCreated(ui.preview.mHolder); 
    ui.preview.surfaceChanged(ui.preview.mHolder, 0, 800, 400); 

ho impostato in modo casuale gli ultimi tre argomenti interi. Quando avvio l'attività, viene visualizzata la finestra di errore nel telefono Android. Dice "Causato da: java.lang.RuntimeException: impossibile connettersi al servizio della fotocamera". Ma come ripararlo ???? Grazie mille!

Gli errori sono:

01-07 00:27:57.173: W/dalvikvm(11625): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0) 
01-07 00:27:57.173: E/AndroidRuntime(11625): FATAL EXCEPTION: main 
01-07 00:27:57.173: E/AndroidRuntime(11625): java.lang.RuntimeException: Unable to resume activity {com.example/com.example.CameraDemo}: java.lang.RuntimeException: Fail to connect to camera service 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2460) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2481) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1847) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.ActivityThread.access$1500(ActivityThread.java:132) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.os.Handler.dispatchMessage(Handler.java:99) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.os.Looper.loop(Looper.java:150) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.ActivityThread.main(ActivityThread.java:4263) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at java.lang.reflect.Method.invokeNative(Native Method) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at java.lang.reflect.Method.invoke(Method.java:507) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at dalvik.system.NativeStart.main(Native Method) 
01-07 00:27:57.173: E/AndroidRuntime(11625): Caused by: java.lang.RuntimeException: Fail to connect to camera service 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.hardware.Camera.native_setup(Native Method) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.hardware.Camera.<init>(Camera.java:265) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.hardware.Camera.open(Camera.java:241) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at com.example.Preview.surfaceCreated(Preview.java:60) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at com.example.CameraDemo.onResume(CameraDemo.java:64) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1242) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.Activity.performResume(Activity.java:3904) 
01-07 00:27:57.173: E/AndroidRuntime(11625): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2450) 
01-07 00:27:57.173: E/AndroidRuntime(11625): ... 12 more 
01-07 00:27:59.455: I/Process(11625): Sending signal. PID: 11625 SIG: 9 
+0

Sento che potrebbe essere correlato alla sequenza di implementazione di onCreate di Acitivity, onResume e alla creazione di superficie, ecc. Sembra che se la classe surfaceView implementa SurfaceHolder.Callback, la superficie non è pronta anche quando siamo al punto di attività in corso. Allora quando siamo pronti? Se Activity implementa SurfaceHolder.Callback, quali sono le sequenze inerenti? Aiuto!!!! – user1914692

risposta

5

si ottiene questo

java.lang.RuntimeException: Fail to connect to camera service 

eccezione, quando la fotocamera viene utilizzata da altre applicazioni. Ma credo che un'altra applicazione sia la tua applicazione stessa. Devi rilasciare la fotocamera.

Questi sono i casi in cui si dovrebbe rilasciare la fotocamera:

Nella classe in anteprima:

public void surfaceDestroyed(SurfaceHolder holder) { 

    // empty. Take care of releasing the Camera preview in your activity. 
    if (mCamera != null) { 
     mCamera.release(); 
    } 
} 

nell'attività:

@Override 
public void onBackPressed() { 
    super.onBackPressed(); 
    if (myCamera != null) { 
     myCamera.release(); 
    } 
    finish(); 
} 

@Override 
protected void onPause() { 
    // TODO Auto-generated method stub 
    super.onPause(); 
    if (myCamera != null) { 
     myCamera.release(); 
    } 
} 

anche su Annulla cliccato, e anche quando lo sei finito di usare la fotocamera i.e .., quando l'immagine viene catturata e si ritorna all'attività.

provare anche questo:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 

    if (mHolder.getSurface() == null) { 
     return; 
    } 

    try { 
     mCamera.stopPreview(); 
    } catch (Exception e) { 
     //You can ignore this, because this means the Preview doesn't Exist 
     //So, no need to try stopping 
    } 

    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 
    } catch (Exception e) { 
     //Catch this 
    } 
} 
+0

Grazie mille. Ho incluso queste funzioni di rilascio della fotocamera in quei luoghi. E la prima versione della mia app funziona molto bene. Come ho detto, voglio spostare i comandi in surfaceCreated e surfaceChanged su onResume. Il problema è che la prima chiamata di onResume non funziona. Quindi immagino che possa essere correlato alle relazioni tra onResume e le chiamate alla superficie. E la tua opinione? – user1914692

+0

Ha funzionato per me !! – GAMA

0

trovo in alcuni esempi, il codice open fotocamera è incluso sia nella surfaceChanged, e nel onResume, utilizzando una frase se per evitare ripetizioni. Forse questo è un modo per risolvere il problema.

1

Così ho creato un'app che utilizzava la fotocamera ma un'icona di lancio diversa per accedere alla pagina delle impostazioni. Quindi ogni volta che ho messo in pausa e ridotto a icona l'app per modificare le impostazioni e l'ho riavviata si è anche arrestata in modo anomalo con questo errore. Quindi dopo molte ricerche non ho ancora avuto risposta. Poi ho capito che questo aveva a che fare con la gestione del ciclo di vita della macchina fotografica. Così è andato e guardato il ciclo di vita, in particolare a Pausing. Quindi ho realizzato, stiamo facendo tutto questo con il metodo sbagliato. Dove lo stiamo facendo su onResume, dovremmo farlo su Start. E BAM! ha funzionato.

Ecco il mio codice per la mia app.

@Override 
    protected void onPause() { 
     super.onPause(); 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.release();  // release the camera for other applications 
      mCamera = null; 
     } 
     if (mPreview != null) { 
      FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer); 
      preview.removeView(mPreview); 
      mPreview = null; 
     } 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     if (mCamera != null) { 
      mCamera.stopPreview(); 
      mCamera.release();  // release the camera for other applications 
      mCamera = null; 
     } 
     if (mPreview != null) { 
      FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer); 
      preview.removeView(mPreview); 
      mPreview = null; 
     } 
    } 
    @Override 
    protected void onResume() { 
     super.onResume(); 

    } 

    @Override 
    protected void onStart(){ 
     super.onStart(); 
//Check if the camera exists or not so it does not clash with the onCreate 
     if(mCamera == null){ 
      dir_string = new File("/storage/sdcard1/app"); 
      Log.d("TAG",dir_string.toString()); 
      mCamera = getCameraInstance(); 
      mPreview = new CameraPreview(this, mCamera); 
      FrameLayout preview = (FrameLayout) findViewById(R.id.camera_viewer); 
      preview.addView(mPreview); 
     } 
    } 

Spero che questo aiuti almeno qualcuno.

+0

non funziona. – exshinigami

+0

Qual è il tuo errore che stai ricevendo? – user2365554

Problemi correlati