HTC Desire HD 不接受带有 hardware.Camera 的 setParameter()
我是一名学生,正在 Android 2.2 上开发一个项目。对于我的测试和应用程序执行,我使用 HTC Desire HD(配备 Android 2.2)。
我只想创建一个组合(类)来用移动设备拍照。我有一个 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();
}
}
最后的问题是:如果设备正在显示相机视图,则设备完全迷失方向。如果我将相机指向房间的顶部(拍摄的场景),屏幕就会向左移动,如果我将相机放在地面上,屏幕就会向右移动。横向屏幕也存在同样的问题,高度和宽度以及相机方向错误。
是否有解决方案可以解决 HTC Desire HD 的 Camera API 的此问题?
谢谢,
相关链接:
I'm a student and I am developing on Android 2.2 for a project. For my tests and app executions, I am using an HTC Desire HD (with Android 2.2).
I just want to create a composant (class) to take a picture with the mobile device. I have an Android class, which I use for the getOptimalPreviewSize() method (this method is in the ApiDemos 2.2). This method is used to fix this type of error :
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)
So, I fixed this problem with this code :
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();
}
}
The final problem is : if the device is displaying the Camera View, the device is totally disoriented. If I point the camera to the top of a room (the scene which is filmed), the screen goes to the left, if I put the Camera to the ground, the screen goes the right. There is the same problem with landscape screen with wrong height and width and Camera Orientation.
Is there a solution to fix this problem of Camera API with the HTC Desire HD ?
Thanks,
Related links :
Android 2.2 SDK - setParameters failed for Camera API on Nexus One
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题不在于您的手机,而在于您为相机分辨率设置的参数。我在学习使用 Nexus One 上的相机时遇到了类似的问题。您需要获取适用于代码正在处理的手机的已知分辨率列表,并将其设置为其中之一。
您确定获取参数不起作用吗?你能发布不起作用的代码吗?也许你做错了。
The problem isn't to do with your phone but rather the parameters you're setting for the camera resolution. I had a similar issue when learning to use the camera on a Nexus One. You need to get a list of known resolutions which works on the phone the code is working on and set it to one of those.
Are you sure get parameters doesn't work? can you post the code which didn't work? perhaps you're doing it wrong.
好吧,我发现了另一个简单的解决方案:
在 Android Manifest 中,将这个属性添加到相机活动中:
并且,在 SurfaceChanged 的相机应用程序中:
就是这样:
问候。
Okay, I Discover another simple solution :
In Android Manifest, add to camera activity this property :
And, in Camera App for surfaceChanged :
just this :
Regards.