SurfaceView Camera.getCameraParameters 返回 null 引用



我正在使用表面视图构建一个相机应用程序,经过几次测试后它运行良好,然后随后的测试看到该应用程序在logcat中崩溃并出现以下异常:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Camera$Parameters android.hardware.Camera.getParameters()' on a null object reference
at com.jjoey.envisionocr.MainActivity.setCameraFocus(MainActivity.java:102)
at com.jjoey.envisionocr.MainActivity.startCamera(MainActivity.java:54)
at com.jjoey.envisionocr.MainActivity.checkPerms(MainActivity.java:69)
at com.jjoey.envisionocr.MainActivity.onCreate(MainActivity.java:37)
at android.app.Activity.performCreate(Activity.java:6671)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)

这发生在代码中的此行号上:Camera.Parameters parameters = camera.getParameters();我已致电Camera.open(id) with the id set to back camera.

这是我的活动代码:

public class MainActivity extends AppCompatActivity {
private FrameLayout frameLayout; //camera surface container
private ImageView captureImgBtn;
private Camera camera;
private CameraPreview preview;
private int type = 0;
public static final int REQ_CAMERA = 102;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPerms();
initViews();
//        startCamera();
captureImgBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
camera.takePicture(mShutterCallback, null, mPictureCallback);
}
});
}
private void startCamera() {
if (checkCameraHardware()){
setCameraFocus();
camera = getCameraInstance(type);
preview = new CameraPreview(this, camera, type);
frameLayout.addView(preview);

} else {
Toast.makeText(getApplicationContext(), "Device not support camera feature", Toast.LENGTH_SHORT).show();
}
}
private void checkPerms() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){
askPerms();
} else {
startCamera();
}
}
private void askPerms() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQ_CAMERA);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQ_CAMERA:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
startCamera();
} else {
finish();
}
break;
}
}
private void releaseCameraAndPreview() {
if (camera != null) {
camera.release();
camera = null;
}
}
private void setCameraFocus() {
releaseCameraAndPreview();
Camera.Parameters parameters = camera.getParameters();
if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
} else {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
camera.setParameters(parameters);
}
private Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() {
@Override
public void onShutter() {
// do ntn
}
};
private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] bytes, Camera camera) {
}
};
private Camera getCameraInstance(int type) {
Camera cam = null;
try {
cam = Camera.open(type);
} catch (Exception e){
Log.d("tag", "Error setting camera not open " + e);
e.printStackTrace();
}
return cam;
}
private boolean checkCameraHardware() {
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
return true;
} else {
return false;
}
}
private void initViews() {
frameLayout = (FrameLayout) findViewById(R.id.frameCamera);
captureImgBtn = findViewById(R.id.captureImgBtn);
}
}

我创建了像这样的 CameraPreview 类:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private Context context;
private SurfaceHolder holder;
private Camera camera;
private int cameraType;
public CameraPreview(Context context, Camera camera, int cameraType) {
super(context);
this.context = context;
this.camera = camera;
this.cameraType = cameraType;
holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
camera.setPreviewDisplay(surfaceHolder);
setCameraDisplayOrientation((Activity) context, cameraType, camera);
camera.startPreview();
} catch (IOException e) {
Log.d("tag", "Error setting camera preview: " + e.getMessage());
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
if (holder == null)
return;
try {
camera.stopPreview();
camera.setPreviewDisplay(surfaceHolder);
setCameraDisplayOrientation((Activity) context, cameraType, camera);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;  // compensate the mirror
} else {  // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
camera.release();
}
}

有谁知道为什么会出现此错误以及如何解决它?我已经尝试了这种方法在打开相机之前释放相机,如下所示:

private void releaseCameraAndPreview() {
if (camera != null) {
camera.release();
camera = null;
}
}

但这似乎不是解决方案。任何帮助将不胜感激。谢谢。

releaseCameraAndPreview()的调用是将camera对象设置为null。因此,当您调用camera.getParameters()时,您正在尝试在null上调用方法。

最新更新