我根据提供的here代码示例构建了一个Camera,并使用来自AOSP GingerBread的Camera.java和ShutterButton.java对其进行了增强,我带走的代码主要用于自动对焦和ShutterButton 。相机已经在Samsung Galaxy Nexus
以及运行4.0.x的Samsung Galaxy S4
和LG Optimus
手机上进行了测试。但是,在appthwack.com上进行测试时结果为{{3}这是我的Camera.open代码无效:
try{
Camera.open();
}
catch(Exception ex)
{
Log.e(TAG,"Could not open camera",ex);//running on HTC prints could not open camera
}
mPreview=new CameraPreview(this,mCamera);//this is which the NullPointerException is thrown
上面的代码在Activity的onResume中调用,这意味着只有当用户看到屏幕时才使用Camera对象,我会在onPause()中释放Camera,如下所示:
sensorManager.unregisterListener(this);
isPreviewShowing=false;
if(mCamera!=null)
killCamera();
container.removeAllViews();
private void killCamera()
{
if(mCamera!=null)
{
mCamera.cancelAutoFocus();
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
mCamera=null;
}
}
我已将打开相机的代码更改为:
Camera.CameraInfo info=new Camera.CameraInfo();
int cameraCount=mCamera.getNumberOfCameras();
int cameraIndex=0;
for(cameraIndex=0;cameraIndex<cameraCount;cameraIndex++)
{
Camera.getCameraInfo(cameraIndex, info);
if(info.facing==CameraInfo.CAMERA_FACING_BACK)
{
try
{
mCamera=Camera.open(cameraIndex);
}
catch(Exception ex)
{
Log.e(TAG, "Could not open camera",ex);
}
}
}
这也不起作用,我还尝试将以下代码添加到CameraPreview
类中:
@SuppressWarnings("deprecation")
public CameraPreview(Context context,Camera camera) {
super(context);
this.ctx=context;
mCamera=camera;
mHolder=this.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if(mCamera==null)
{
mCamera=null;
Camera.CameraInfo info=new Camera.CameraInfo();
int cameraCount=mCamera.getNumberOfCameras();
int cameraIndex=0;
for(cameraIndex=0;cameraIndex<cameraCount;cameraIndex++)
{
Camera.getCameraInfo(cameraIndex, info);
if(info.facing==CameraInfo.CAMERA_FACING_BACK)
{
try
{
mCamera=Camera.open(cameraIndex);
}
catch(Exception ex)
{
Log.e(TAG, "Could not open camera",ex);
}
}
}
}
try
{
if(mCamera==null)
{
Log.d(TAG,"Camera is null here but why???");
}
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch(IOException e)
{
Log.e("CameraPreview","Error getting camera preview",e);
}
}
这也不起作用。另外,对于任何问我权限的人,我已将所有必需的权限声明为:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera"
android:required="true"
/>
<uses-feature android:name="android.hardware.camera.autofocus"
android:required="true"
/>
<uses-feature android:name="android.hardware.sensor.accelerometer"
android:required="true"
/>
开始使用全新的相机会有点困难,我想(如果可能的话)保持相机的现有结构完好无损,那么请你帮我解决这个问题。整个logcat文件随上面公布的测试结果一起提供。
通过surfaceCreated使用全局SurfaceHolder对象而不是持有者提供者上的持有者解决了HTC Desire HD上的问题,而不是HTC One S.It会在此处引发错误:
java.lang.NullPointerException at
com.blutechnologies.scancard.CameraPreview.surfaceCreated(CameraPreview.java:95) at
android.view.SurfaceView.updateWindow(SurfaceView.java:543) at
android.view.SurfaceView.access$000(SurfaceView.java:81) at
android.view.SurfaceView$3.onPreDraw(SurfaceView.java:169) at
android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:590) at
android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1793) at
android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2700) at
android.os.Handler.dispatchMessage(Handler.java:99) at
android.os.Looper.loop(Looper.java:156) at
android.app.ActivityThread.main(ActivityThread.java:5045) at
java.lang.reflect.Method.invokeNative(Native Method) at
java.lang.reflect.Method.invoke(Method.java:511) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at
dalvik.system.NativeStart.main(Native Method)
这之前是:
I ActivityManager START {cmp=com.blutechnologies.scancard/.CameraActivity} from pid 21085
I QualcommCamera Qint android::get_camera_info(int, camera_info*): E
V QCameraHAL void android::HAL_getCameraInfo(int, android::CameraInfo*): E
V QCameraHAL void android::HAL_getCameraInfo(int, android::CameraInfo*): X
我想这意味着相机正在忙碌,即它正在其他地方使用,是因为之前设备发生了崩溃,如果我将相机关闭代码放在surfaceDestroyed
中,它是否会自行纠正,这样做似乎非常危险,我将此代码添加到我的surfaceDestroyed:
private void killCamera()
{
if(mCamera!=null)
{
mCamera.cancelAutoFocus();
mCamera.release();
mCamera=null;
}
}
相机现在是空白的,根本没有显示预览,它在设置预览尺寸时卡住了。必须有一些我没做的事情可以解决这个错误。
答案 0 :(得分:2)
这是如何获取相机的示例:
private Camera getCameraInstance() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
Camera.getCameraInfo( camIdx, cameraInfo );
if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK ) {
try {
cam = Camera.open( camIdx );
} catch (RuntimeException e) {
Log.e("Camera", "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
并检查清单中的权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
答案 1 :(得分:0)
我不知道究竟是什么问题,但是您在surfaceCreated
上编写代码,但我还有其他一些技巧。
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
**OnCreate**
...
...
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
<强> OnPreviewStart()强>
OnPreviewStart() {
if (!previewing) {
camera = Camera.open();
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
<强> onPreviewStop()强>
onPreviewStop() {
if (camera != null && previewing) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
您可以在任何您想要使用的地方调用以上两个功能,以显示&amp;表面上的相机预览。
下一件事implements SurfaceHolder.Callback
那将@Override三种方法表面很少像
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}
public void surfaceCreated(SurfaceHolder holder){}
public void surfaceDestroyed(SurfaceHolder holder){}