Android: Take picture and save picture on SD Card

2019-07-17 18:22发布

问题:

I want to take a picture with my phone via an application and save the image on my phone. I've tried many of the solutions proposed on the stackoverflow questions but it did not mark so I built a method that saves the file with the right name ... but the file is empty (0kb)!

Here is my code

public class GameActivity extends Activity implements SurfaceHolder.Callback/*,Camera.PictureCallback*/ {

private Camera camera;
private SurfaceView surfaceCamera;
public Handler handler = new Handler(); 
private boolean isPreview=false;
private SurfaceHolder holder;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gameactivity);
    surfaceCamera = (SurfaceView) findViewById(R.id.surfaceViewCamera);
    getWindow().setFormat(PixelFormat.UNKNOWN);
    holder = surfaceCamera.getHolder();
    holder.addCallback(this);
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    ImageView image = (ImageView) findViewById(R.id.imageView3);
    image.setOnTouchListener(new OnTouchListener(){

        @Override
        public boolean onTouch(View arg0, MotionEvent arg1) {
   camera.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);     
            return false;

}


Camera.ShutterCallback myShutterCallback = new Camera.ShutterCallback() {
    public void onShutter() {
      // TODO bl
    }
  };

PictureCallback myPictureCallback_RAW = new PictureCallback() {

    public void onPictureTaken(byte[] arg0, Camera arg1) {
        // TODO Auto-generated method stub

    }
};


PictureCallback myPictureCallback_JPG = new PictureCallback(){

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
            File imagesFolder = new File(Environment.getExternalStorageDirectory(), "/KersplattFolder");
            imagesFolder.mkdirs(); 
            String fileName = "image.jpg";
            File output = new File(imagesFolder, fileName);
            try {
                FileOutputStream fos = new FileOutputStream(output);
                fos.write(data[0]);
                fos.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

                Toast.makeText(GameActivity.this, 
                        "Image saved: ", 
                        Toast.LENGTH_LONG).show();
            camera.startPreview();
            }
};


@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    if (isPreview) {
        camera.stopPreview();
    }
    Camera.Parameters p = camera.getParameters();
    p.setPreviewSize(width,height);
    camera.setParameters(p);
    try {
        camera.setPreviewDisplay(holder);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    camera.startPreview();
    isPreview=true;
}


@Override
public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();

}


@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    isPreview=false;
    camera.release();

}

EDIT1 : when I put data instead of data[0] I save a black image as well but the file has a weight so I guess the real image is somewhere...

EDIT2 I have added the code

                File output = new File(imagesFolder, fileName);
            Uri outputFileUri = Uri.fromFile(output);
            String filePath = outputFileUri.getPath();
            File file= new File(filePath);
            try {
                FileOutputStream fos = new FileOutputStream(file,true);
                fos.write(data);
                fos.close();
            } 

Still have the black image

回答1:

have you defined the required permissions in your Android manifest like described here?

<manifest ... >
    <uses-feature android:name="android.hardware.camera" />
    ...
</manifest ... >

UPDATE: Ok, remove the brackets after data: data instead of data[]. Then it should work.



回答2:

Your code: fos.write(data[0]); is wrong. I am surprised that you did not get an exception

Here is the code I used to save the byte array after taking a picture. "data" is the byte array.

String filePath = outputFileUri.getPath(); // .getEncodedPath();
    File file = new File(filePath);
    FileOutputStream os;
    try {
        os = new FileOutputStream(file, true);
        os.write(data);
        os.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }