2011-02-14 54 views
2

我是學生,我在Android 2.2開發的項目。對於我的測試和應用程序執行,我正在使用HTC Desire HD(搭配Android 2.2)。HTC Desire HD的不接受的setParameter()與hardware.Camera

我只是想創建一個composant(類)採取與移動設備的圖片。我有一個Android類,用於getOptimalPreviewSize()方法(此方法位於ApiDemos 2.2中)。這種方法被用來修正此類型的錯誤:

02-14 21:38:05.818: ERROR/AndroidRuntime(2884): java.lang.RuntimeException: Fail to connect to camera service 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.hardware.Camera.native_setup(Native Method) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.hardware.Camera.<init>(Camera.java:118) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.hardware.Camera.open(Camera.java:91) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at com.example.android.apis.graphics.Preview.surfaceCreated(CameraPreview.java:69) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.SurfaceView.updateWindow(SurfaceView.java:540) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.SurfaceView.dispatchDraw(SurfaceView.java:339) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.ViewGroup.drawChild(ViewGroup.java:1660) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1389) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.View.draw(View.java:6764) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.ViewGroup.drawChild(ViewGroup.java:1662) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1389) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.View.draw(View.java:6764) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1887) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.ViewRoot.draw(ViewRoot.java:1422) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1167) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1744) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.os.Looper.loop(Looper.java:143) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at android.app.ActivityThread.main(ActivityThread.java:5068) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at java.lang.reflect.Method.invoke(Method.java:521) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
02-14 21:38:05.818: ERROR/AndroidRuntime(2884):  at dalvik.system.NativeStart.main(Native Method) 

所以,我固定此問題與此代碼:

public class CameraView extends Activity implements SurfaceHolder.Callback { 

private SurfaceView mSurfaceView = null; 
private SurfaceHolder mSurfaceHolder = null; 
private Camera mCamera = null; 
private boolean mPreviewRunning = false;  

public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 

    getWindow().setFormat(PixelFormat.TRANSLUCENT); 
    //requestWindowFeature(Window.FEATURE_NO_TITLE); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 
    setContentView(R.layout.camera_surface); 
    mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera); 
    mSurfaceHolder = mSurfaceView.getHolder(); 
    mSurfaceHolder.addCallback(this); 
    mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    if (!(android.os.Environment.getExternalStorageState().equals(
      android.os.Environment.MEDIA_MOUNTED))) 
    { 
     Toast 
     .makeText(CameraView.this, R.string.msgNoSdCard, Toast.LENGTH_LONG) 
     .show(); 
    } 
    else 
    { 
     Toast 
     .makeText(CameraView.this, R.string.msgPressBackBt, Toast.LENGTH_LONG) 
     .show(); 
    } 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    // TODO Auto-generated method stub 
    mCamera = Camera.open(); 
    try { 
      mCamera.setPreviewDisplay(holder); 
     } catch (IOException exception) { 
      mCamera.release(); 
      mCamera = null; 
      // TODO: add more exception handling logic here 
     } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    mCamera.stopPreview(); 
    mPreviewRunning = false; 
    mCamera.release(); 
} 

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    //Handle the back button 
    if ((keyCode == KeyEvent.KEYCODE_DPAD_CENTER) || (keyCode == KeyEvent.KEYCODE_CAMERA)){ 
     mCamera.takePicture(shutterCallback, rawCallback, jpegCallback); 
     return true; 
    } 
    else { 
     return super.onKeyDown(keyCode, event); 
    } 
} 

ShutterCallback shutterCallback = new ShutterCallback() {  
    public void onShutter() {      
    } 
}; 


/** Handles data for raw picture */ 
PictureCallback rawCallback = new PictureCallback() {  
    public void onPictureTaken(byte[] data, Camera camera) {        
    } 
}; 

/** Handles data for jpeg picture */  
PictureCallback jpegCallback = new PictureCallback() {  
    public void onPictureTaken(byte[] data, Camera camera) {    
     FileOutputStream outStream = null;   
     try {    
      // write to local sandbox file system    
      //outStream =    
      //CameraView.this.openFileOutput(String.format("%d.jpg",     
      //System.currentTimeMillis()), 0);    
      // Or write to sdcard    
      long fileName = System.currentTimeMillis(); 
      outStream = new FileOutputStream(String.format(      
        "/sdcard/%d.jpg", fileName));    
      outStream.write(data);    
      outStream.close();    

      Intent resultIntent = new Intent();  
      String imageFileName = String.format("/sdcard/%d.jpg", fileName); 
      resultIntent.putExtra("MyAvatar", imageFileName); 
      setResult(Activity.RESULT_OK, resultIntent); 


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

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { 
    final double ASPECT_TOLERANCE = 0.05; 
    double targetRatio = (double) w/h; 
    if (sizes == null) return null; 

    Size optimalSize = null; 
    double minDiff = Double.MAX_VALUE; 

    int targetHeight = h; 

    // Try to find an size match aspect ratio and size 
    for (Size size : sizes) { 
     double ratio = (double) size.width/size.height; 
     if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; 
     if (Math.abs(size.height - targetHeight) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(size.height - targetHeight); 
     } 
    } 

    // Cannot find the one match the aspect ratio, ignore the requirement 
    if (optimalSize == null) { 
     minDiff = Double.MAX_VALUE; 
     for (Size size : sizes) { 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 
    } 
    return optimalSize; 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
    // Now that the size is known, set up the camera parameters and begin 
    // the preview. 
    Camera.Parameters parameters = mCamera.getParameters(); 

    List<Size> sizes = parameters.getSupportedPreviewSizes(); 
    Size optimalSize = getOptimalPreviewSize(sizes, w, h); 
    parameters.setPreviewSize(optimalSize.width, optimalSize.height); 

    mCamera.setParameters(parameters); 
    mCamera.startPreview(); 
} 

} 

的最後一個問題是:如果該裝置顯示所述相機視圖中,設備完全迷失方向。如果我將相機指向房間頂部(拍攝的場景),屏幕會向左移動,如果將相機放在地面上,屏幕會向右移動。橫向屏幕有相同的問題,高度和寬度以及相機方向錯誤。

有固定攝像頭API的這個問題與HTC Desire HD的解決方案嗎?

感謝,

相關鏈接:

Android 2.2 SDK - setParameters failed for Camera API on Nexus One

http://code.google.com/p/android/issues/detail?id=7909

+0

它被認爲是好形式「接受」的答案,如果它幫助您解決問題。您可以通過點擊最佳答案左側的「打勾」來完成此操作。 – 2011-11-15 16:09:37

回答

0

好吧,我發現另一個簡單的解決方案:

在Android清單,增加攝像頭的活動這個屬性:

android:screenOrientation="landscape" 

而且,在相機應用的surfaceChanged:

剛這樣的:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     Camera.Parameters parameters = mCamera.getParameters(); 
     mCamera.setParameters(parameters); 
     mCamera.startPreview(); 
} 

此致敬禮。

3

的問題是不與您的手機,而是參數你設置相機的分辨率做。在學習在Nexus One上使用相機時,我遇到了類似的問題。您需要獲取代碼正在處理的已知分辨率列表,並將其設置爲其中的一個分辨率。

確實得到參數不起作用?你可以發佈沒有用的代碼嗎?也許你做錯了。

0
Ok, problem resolved with this code : 



@Override 
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
      // Now that the size is known, set up the camera parameters and begin 
      // the preview. 
      Camera.Parameters parameters = mCamera.getParameters(); 

      List<Size> sizes = parameters.getSupportedPreviewSizes(); 
      Size optimalSize = getOptimalPreviewSize(sizes, w, h); 
      parameters.setPreviewSize(optimalSize.width, optimalSize.height); 
      mCamera.setDisplayOrientation(90); 
      parameters.setRotation(90); 
      mCamera.setParameters(parameters); 
      mCamera.startPreview(); 
     } 
相關問題