代码之家  ›  专栏  ›  技术社区  ›  Andromeda

surfaceview camera.getcamerarparameters返回空引用

  •  0
  • Andromeda  · 技术社区  · 6 年前

    我正在使用Surface View构建一个摄像头应用程序,经过几次测试后运行良好,随后的测试在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;
        }
    }
    

    但这似乎不是解决办法。任何帮助都将不胜感激。谢谢。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Larry Schiefer    6 年前

    对…的呼唤 releaseCameraAndPreview() 正在设置 camera 反对 null 是的。所以当你打电话 camera.getParameters() 您正在尝试调用 无效的 是的。