2013-10-16 1 views
0

Следующий код тестируется на HTC Desire S, Galaxy S II и эмуляторе. Он работает нормально, но на удивление он не работает на Galaxy S Duos (GT-S7562). Случается, что все вызовы успешны без исключения, но вызываемые вызовы не вызываются.Samsung Galaxy Duos (GT-S7562) Camera.takePicture, но звонок не вызван

public class CameraManager implements PictureCallback { 
    private final static String DEBUG_TAG = "CameraManager"; 

public void TakePicture() { 
     try { 
      _camera = Camera.open(cameraId); 
      Log.d(DEBUG_TAG, "Camera.TakePicture.open"); 
      SurfaceView view = new SurfaceView(CameraManager.this.getContext()); 
      _camera.setPreviewDisplay(view.getHolder()); 
      Log.d(DEBUG_TAG, "Camera.TakePicture.setPreviewDisplay"); 
      _camera.startPreview(); 
      Log.d(DEBUG_TAG, "Camera.TakePicture.startPreview"); 

      AudioManager manager = (AudioManager) CameraManager.super.getContext().getSystemService(Context.AUDIO_SERVICE); 
      Log.d(DEBUG_TAG, "Camera.TakePicture.AudioManager.ctor()"); 
      manager.setStreamVolume(AudioManager.STREAM_SYSTEM, 0 , AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); 
      Log.d(DEBUG_TAG, "Camera.TakePicture.setStreamVolume"); 

      Camera.ShutterCallback shutter = new Camera.ShutterCallback() { 
       @Override 
       public void onShutter() { 
        AudioManager manager = (AudioManager) CameraManager.super.getContext().getSystemService(Context.AUDIO_SERVICE); 
        Log.d(DEBUG_TAG, "Camera.TakePicture.Shutter.AudioManager.ctor()"); 
        manager.setStreamVolume(AudioManager.STREAM_SYSTEM, manager.getStreamMaxVolume(AudioManager.STREAM_SYSTEM) , AudioManager.FLAG_ALLOW_RINGER_MODES); 
        Log.d(DEBUG_TAG, "Camera.TakePicture.Shutter.setStreamVolume"); 
       } 
      }; 

      Camera.PictureCallback rawCallback = new Camera.PictureCallback() { 
       @Override 
       public void onPictureTaken(byte[] data, Camera camera) { 
        if (data != null) { 
         Log.i(DEBUG_TAG, "Picture taken::RAW"); 
         _camera.stopPreview(); 
         _camera.release(); 
        } else { 
         Log.wtf(DEBUG_TAG, "Picture NOT taken::RAW"); 
        } 
       } 
      }; 
      _camera.takePicture(shutter, rawCallback, CameraManager.this); 
      Log.d(DEBUG_TAG, "Camera.TakePicture.taken"); 
     } catch (Exception err) { 
      err.printStackTrace(); 
      Log.d(DEBUG_TAG, "Camera.TakePicture.Exception:: %s" + err.getMessage()); 
     } 
    } 


    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     if (data != null) { 
      Log.i(DEBUG_TAG, "Picture taken::JPG"); 
      _camera.stopPreview(); 
      _camera.release(); 
     } else { 
      Log.wtf(DEBUG_TAG, "Picture NOT taken::JPG"); 
     } 
    } 
} 

Вот вывод журнал LogCat для выполнения приведенного выше кода, как вы можете видеть, обратные вызовы не называются .:

[ 10-16 01:39:18.711 3873:0xf21 D/CameraManager ] 
Camera.TakePicture.open 

[ 10-16 01:39:18.891 3873:0xf21 D/CameraManager ] 
Camera.TakePicture.setFrontCamera 

[ 10-16 01:39:18.901 3873:0xf21 D/CameraManager ] 
Camera.TakePicture.setPreviewDisplay 

[ 10-16 01:39:18.901 3873:0xf21 D/CameraManager ] 
Camera.TakePicture.startPreview 

[ 10-16 01:39:18.901 3873:0xf21 D/CameraManager ] 
Camera.TakePicture.AudioManager.ctor() 

[ 10-16 01:39:19.001 3873:0xf21 D/CameraManager ] 
Camera.TakePicture.setStreamVolume 

[ 10-16 01:39:19.041 3873:0xf21 D/CameraManager ] 
Camera.TakePicture.taken 

Я также проверил SO для подобных проблем, с Galaxy S и нашел следующий код, я использовал его без успеха:

Camera.Parameters parameters = camera.getParameters(); 
parameters.set("camera-id", 2); 
// (800, 480) is also supported front camera preview size at Samsung Galaxy S. 
parameters.setPreviewSize(640, 480); 
camera.setParameters(parameters); 

Мне было интересно, может ли кто-нибудь сказать мне, что случилось с моим кодом? или, возможно, есть некоторые ограничения с этой моделью, которая не позволяет делать снимки, не показывая поверхность предварительного просмотра. Если да, тогда вы могли бы сообщить мне о возможном обходном пути? Обратите внимание, что этот код выполняется из службы android.

ответ

0

Documentation ясно: вы должны начать просмотр, если хотите сделать снимок. Из вашего кода неясно, почему поверхность предварительного просмотра не отображается. IIRC, в Honeycomb и позже, вы не можете играть с координатами поверхности предварительного просмотра, чтобы переместить его с экрана. Но вы можете скрыть поверхность предварительного просмотра за некоторым видом изображения.

+0

Код запускается из службы android, и, как вы можете видеть, фиктивный SurfaceView передается методу setPreviewDisplay, поэтому не будет отображаемой поверхности предварительного просмотра. После документации не то, что я ищу, код работает на некоторых устройствах, поэтому то, что я пытаюсь сделать, не ограничено самим Android sdk, а ограничено производителями устройств. Другими словами, речь идет скорее о проблеме совместимости, чем о ограничении sdk. – Farzan

+0

Я заметил, что вы пытаетесь заставить замолчать затвор. Это может быть против правил на некоторых рынках. Если тестируемое устройство соответствует таким правилам, оно молча игнорирует попытку захвата изображения без звука затвора. –

+0

Итак, вы предполагаете, что если я не буду отключать звук затвора, проблема может быть решена? – Farzan