2010-01-12 8 views

Odpowiedz

41

Najprawdopodobniej masz nieprawidłowy rozmiar podglądu. Jeśli zaznaczysz wyniki adb logcat prawdopodobnie zobaczysz coś takiego:

E/QualcommCameraHardware(22732): Invalid preview size requested: 480x724 

Rozwiązaniem jest poprosić najbliższy dostępny rozmiar podglądu do jednego chcesz; można uzyskać listę dostępnych rozmiarów podglądu, wywołując getSupportedPreviewSizes w obiekcie Camera.Parameters zwróconym przez obiekt zwrócony przez Camera.getParameters.

+0

Masz rację, chyba że została ona próbuje ustawić ją na 320x480 i 480x320 będzie pracował. Prowadzi mnie to do następnego pytania, dlaczego wywoływana była metoda SurfaceHolder.Callback.surfaceChanged() z tak niską rozdzielczością, która nie pasuje nawet do proporcji urządzenia? –

+2

@Erik B - Zdaję sobie sprawę, że odpowiedź na ten komentarz jest spóźniona, ale prawdopodobnie jest tak, ponieważ Twoja aplikacja jest w trybie zgodności, a system traktuje piksele w aplikacji jako 0.66x rzeczywistą rozdzielczość urządzenia. Tak więc 480x800 będzie prezentowane Twojej aplikacji jako 320 x 533, prawdopodobnie goląc kilka pikseli w poziomie lub pionie dla paska stanu, chyba że Twoja aktywność jest pełnoekranowa. –

+0

Co robisz przed wersją API 5? (Powiedzmy, że chcę być kompatybilny z Androidem 1.5) – uvgroovy

26

poprawiłem to robiąc to, co powiedział Roman, z kodem:

Camera.Parameters parameters = camera.getParameters(); 
    List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
    Camera.Size cs = sizes.get(0); 
    parameters.setPreviewSize(cs.width, cs.height); 
    camera.setParameters(parameters); 
10

Na co warto, źródłem mojego problemu skończył się, że próbowałem zadzwonić parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); bez uprzedniego sprawdzenia, że ​​tryby pracy lampy błyskowej były obsługiwane przez sprawdzenie, czy parameters.getFlashMode() != null.

Istnieje więcej niż jedna przyczyna tego źle udokumentowanego wyjątku, więc sprawdź wszystkie parametry, a nie tylko, czy używasz supportedPreviewSize.

+0

To mi pomogło. :) dziękuję za udostępnienie –

+1

jeśli (! getBaseContext(). getPackageManager(). hasSystemFeature ( PackageManager.FEATURE_CAMERA_FLASH)) { // Lampa błyskowa aparatu nie jest dostępna na urządzeniu } –

2

Żadne z powyższych nie rozwiązało tego problemu. Dodanie tego kodu przed ustawieniem parametrów jednak.

// stop preview before making changes 
    try { 
     mCamera.stopPreview(); 
    } catch (Exception e){ 
     // ignore: tried to stop a non-existent preview 
    } 

//now set your parameters 
0

Niektóre open source projekt kamera jak opencamera zawsze używać try-catch zadzwonić Camera.setParameters:

private void setCameraParameters(Camera.Parameters parameters) { 
    if(MyDebug.LOG) 
     Log.d(TAG, "setCameraParameters"); 
    try { 
     camera.setParameters(parameters); 
     if(MyDebug.LOG) 
      Log.d(TAG, "done"); 
    } catch (RuntimeException e) { 
     // just in case something has gone wrong 
     if(MyDebug.LOG) 
      Log.d(TAG, "failed to set parameters"); 
     e.printStackTrace(); 
     count_camera_parameters_exception++; 
    } 
} 

Ponadto zawsze uzyskać najnowsze getParameters przed wywołaniem setParameters tak:

void setRotation(int rotation) { 
    Camera.Parameters parameters = this.getParameters(); 
    parameters.setRotation(rotation); 
    setCameraParameters(parameters); 
} 
0

Rozwiązanie z Sam jest poprawne, ale obraz wyjściowy jest nadal powiększany trochę na kilku tabletach. Jedną z najlepszych praktyk, które znalazłem w Internecie, powinniśmy ustawić Host kamery, aby właściwości były ponownie używane za każdym razem, gdy aparat jest wznawiany. Tutaj jest realizowany w sposób CameraHost:

@Override 
     public Parameters adjustPreviewParameters(Parameters parameters) { 
      List<Camera.Size> sizes = parameters.getSupportedPreviewSizes(); 
      Camera.Size cs = sizes.get(0); 
      parameters.setPreviewSize(cs.width, cs.height); 
      return super.adjustPreviewParameters(parameters); 
     } 
2

Dla mnie byłoby to zdarzyć po zrobieniu zdjęć i podglądu by zamrozić, aż aktualizowane mój apel o parametry być następujący. Zawsze jest ważne, aby ten błąd sprawdzał wszystkie parametry, które kamera prosi, aby upewnić się, że każdy parametr, o który pytasz kamerę, jest ustawiony dla kamery.

Camera.Parameters parameters = myCamera.getParameters(); 

Z rozmiaru podglądu:

if (myCamera.getParameters().getSupportedPreviewSizes() != null){ 
    Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);; 
    parameters.setPreviewSize(previewSize.width, previewSize.height); 
} 

Z trybów lampy błyskowej/ostrości:

if(parameters.getSupportedFocusModes() != null && parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){ 
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
} 

if (parameters.getSupportedFlashModes() != null && parameters.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_AUTO)){ 
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 

} 

myCamera.setParameters(parameters); 

itp Wszystko to zapakowane w ładnym try {} catch() {} działa świetnie. Powodzenia.

Oto Rozmiar getOptimalPreview z this great tutorial:

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height) 
    { 
     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     Camera.Size optimalSize = null; 

     final double ASPECT_TOLERANCE = 0.1; 
     double targetRatio = (double) height/width; 

     // Try to find a size match which suits the whole screen minus the menu on the left. 
     for (Camera.Size size : sizes){ 

      if (size.height != width) continue; 
      double ratio = (double) size.width/size.height; 
      if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){ 
       optimalSize = size; 
      } 
     } 

     // If we cannot find the one that matches the aspect ratio, ignore the requirement. 
     if (optimalSize == null) { 
      // TODO : Backup in case we don't get a size. 
     } 

     return optimalSize; 
    } 
Powiązane problemy