2012-02-02 26 views
11

Po wywołaniu Camera.takePicture() mój podgląd przestanie się aktualizować zgodnie z opisem w dokumentacji. Jaki jest najlepszy sposób na wykrycie, że proces przechwytywania obrazu został zakończony i wywołanie funkcji startPreview() w celu ponownego rozpoczęcia aktualizacji?Jaki jest najlepszy sposób wywołania funkcji StartPreview() po przechwyceniu obrazu?

Wywołania nie można umieścić w żadnych wywołaniach przekazywanych do strony TakePicture, zgodnie z dokumentami, ponieważ wszystkie one powróciły przed wywołaniem.

Moje obecne najlepsze przypuszczenie to utworzenie Handler'a i wysłanie z niego opóźnionego wywołania z wywołania zwrotnego w formacie JPEG (lub tego, który z nich jest ostatnim zdefiniowanym wywołaniem zwrotnym do zwrócenia).

Odpowiedz

6

Powinieneś uruchomić obraz mCamera.take z poziomu AsyncTask (lub wątku), jednak opcja AsyncTaks jest łatwiejszą opcją.

Naprawdę prosta implementacja (co oczywiście może być modyfikowana) jest:

Metoda nazywa, aby wykonać zdjęcie

/** 
* Execute the AsyncTask that will handle the preview of the captured photo. 
*/ 
public void takePicture() { 
    TakePictureTask takePictureTask = new TakePictureTask(); 
    takePictureTask.execute(); 
} 

AsyncTask podklasa

/** 
* A pretty basic example of an AsyncTask that takes the photo and 
* then sleeps for a defined period of time before finishing. Upon 
* finishing, it will restart the preview - Camera.startPreview(). 
*/ 

private class TakePictureTask extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected void onPostExecute(Void result) { 
     // This returns the preview back to the live camera feed 
     mCamera.startPreview(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     mCamera.takePicture(null, null, mPictureCallback); 

     // Sleep for however long, you could store this in a variable and 
     // have it updated by a menu item which the user selects. 
     try { 
      Thread.sleep(3000); // 3 second preview 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return null; 
    } 

} 

Pole PictureCallback

private PictureCallback mPictureCallback = new PictureCallback() { 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     File file = null; 

     // Check whether the media is mounted with read/write permission. 
     if (Environment.MEDIA_MOUNTED.equals(
       Environment.getExternalStorageState())) { 
      file = getOutputMediaFile(); 
     } 

     if (file == null) { 
      Log.d(TAG, "Error creating media file, check storage persmissions!"); 
      return; 
     } 

     try { 
      FileOutputStream fileOutputStream = new FileOutputStream(file); 
      fileOutputStream.write(data); 
      fileOutputStream.close(); 
     } catch (FileNotFoundException e) { 
      Log.d(TAG, "File not found: " + e.getMessage()); 
     } catch (IOException e) { 
      Log.d(TAG, "Error accessing file: " + e.getMessage()); 
     } 
    } 
}; 
+0

Czy to, co robią w tym samouczku, jest po prostu błędne? http://developer.android.com/training/camera/cameradirect.html Naprawdę nie rozumiem, jak można uruchomić ponownie podgląd tam, ale nie wygląda to jak AsyncTask czy cokolwiek innego ... – Headcrab

12

Ponieważ PictureCallback rozpoczyna się w osobnym wątku mimo to (nie będzie zablokować UI), nie trzeba używać AsyncTask zadzwonić do schwytania.

Istnieją dwa sposoby, aby robić to, co chcesz zrobić, najłatwiej jest następujący:

mCamera.startPreview(); //preview has to be started before you can take a picture 
mCamera.takePicture(null, null, mPictureCallback); //take a picture 

private PictureCallback mPictureCallback = new PictureCallback() { 
    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     camera.startPreview(); //once your camera has successfully finished 
           //its capture it's safe to restart the preview 
     ... //anything else you want to do to process that image 
    } 
} 

Druga byłaby za pomocą anonimowej funkcji, np:

mCamera.takePicture(null, null, new PictureCallback(){ 
    ... 
}); 

Both mają swoje zastosowania, w zależności od Twoich potrzeb.

+0

Dla 'PictureCallback' do pracy nad jako wątek w tle, kamerę należy otworzyć w osobnym wątku zdarzeń, zobacz [przykład kodu] (http://stackoverflow.com/a/19154438/192373). –

+0

@Alex Rozumiem, że funkcje PictureCallback() i PreviewCallback() (które wymieniono w twoim poście) działają inaczej. Jeśli chcesz wykonać jakąkolwiek pracę nad obrazem wynikowym z PictureCallback(), użyj dla tego wątku. Proszę dać mi znać, jeśli nie rozumiem. – wblaschko

+0

Jest łatwy do sprawdzenia, ale nie znam odpowiedzi ze strony –

Powiązane problemy