以下代码在低于lollipop的android版本中可以正常工作,但在lollipop及更高版本中则无法正常工作。任何人都可以帮忙做什么,以便它可以在所有版本中使用。我已经在许多设备中对其进行了测试,但在棒棒糖中却收到此错误"takePicture failed"

public class CameraService extends Service {
    private Camera camera;
    private int cameraId = 0;
    private Timer timer;

    @Override
    public void onCreate() {
        super.onCreate();

    }

    @Override
    public void onStart(Intent intent, int startId) {
        capureImage();
        super.onStart(intent, startId);
    }

    public void capureImage() {
        try {
            cameraId = findFrontFacingCamera();
            if (cameraId < 0) {
            } else {
                SurfaceView view = new SurfaceView(getApplicationContext());
                safeCameraOpen(cameraId);
                camera.setPreviewDisplay(view.getHolder());
                camera.startPreview();
                Camera.Parameters params = camera.getParameters();
                params.setJpegQuality(100);
                camera.setParameters(params);
                camera.takePicture(null, null, mCall);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    Camera.PictureCallback mCall = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0,
                        data.length);
                saveBitmap(bitmapPicture);
                releaseCamera();
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("exception", e.getMessage());
            }
        }
    };

    private void saveBitmap(Bitmap bmp) {
        String _time = "";
        Calendar cal = Calendar.getInstance();
        int millisecond = cal.get(Calendar.MILLISECOND);
        int second = cal.get(Calendar.SECOND);
        int minute = cal.get(Calendar.MINUTE);
        int hourofday = cal.get(Calendar.HOUR_OF_DAY);
        _time = "image_" + hourofday + "" + minute + "" + second + ""
                + millisecond;
        String file_path = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/DiaryFakeImage";
        try {
            File dir = new File(file_path);
            if (!dir.exists())
                dir.mkdirs();
            File file = new File(dir, _time);
            FileOutputStream fOut = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.PNG, 90, fOut);
            fOut.flush();
            fOut.close();
        } catch (Exception e) {
            Log.e("error in saving image", e.getMessage());
        }
    }

    private boolean safeCameraOpen(int id) {
        boolean qOpened = false;
        try {
            releaseCamera();
            camera = Camera.open(id);
            qOpened = (camera != null);
        } catch (Exception e) {

            e.printStackTrace();
        }
        return qOpened;
    }

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

    private int findFrontFacingCamera() {
        int cameraId = -1;
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                cameraId = i;
                break;
            }
        }
        return cameraId;
    }


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

最佳答案

您需要将SurfaceTexture用于Lollipop。

尝试在camera.startPreview();-之前添加它

SurfaceTexture st = new SurfaceTexture(MODE_PRIVATE);
camera.setPreviewTexture(st);
camera.startPreview();

08-06 05:15