2011-02-14 51 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(); 
     } 
相关问题