Using camera inside an app using surfaceview in an

2019-02-28 21:26发布

问题:

I am creating an app where i can use the camera inside it without going to the default app of the phone.So i have used a surface view and tried to save it onto the phone, but the onPictureTaken never gets called.The complete code is shown below:

package com.example.surfaceviewcamera;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements SurfaceHolder.Callback {

    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    Camera mCamera;
    boolean mPreviewRunning;
    Button btncapture;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btncapture=(Button) findViewById(R.id.btncapture);
        mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        btncapture.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
                    public void onPictureTaken(byte[] imageData, Camera c) {

                        Bitmap bitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length);
                        String file_path=saveToInternalSorage(bitmap);
                        Toast.makeText(getApplicationContext(),"Image stored succesfully at "+file_path,Toast.LENGTH_LONG).show();
                    }

                    };

            }
        });

    }
    private String saveToInternalSorage(Bitmap bitmapImage){
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
         // path to /data/data/yourapp/app_data/imageDir
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        // Create imageDir
        File mypath=new File(directory,"marina1.jpg");

        FileOutputStream fos = null;
        try {           

            fos = new FileOutputStream(mypath);

       // Use the compress method on the BitMap object to write image to the OutputStream
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return directory.getAbsolutePath();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mCamera=Camera.open();


    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w,
            int h) {
        if (mPreviewRunning) {
            mCamera.stopPreview();
            }
            Camera.Parameters p = mCamera.getParameters();
            p.setPreviewSize(w, h);
            mCamera.setParameters(p);
            try {
            mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
            e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;

    }


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

    }

}

My XML file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
 android:layout_height="fill_parent"
android:orientation="vertical">

<SurfaceView
 android:id="@+id/surface_camera"
android:layout_width="fill_parent"
 android:layout_height="10dip"
android:layout_weight="1">
</SurfaceView>
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="CAPTURE IMAGE"
    android:id="@+id/btncapture"
    android:layout_gravity="center"
    />
</LinearLayout>

回答1:

call camera.takePicture(null, null, callback); from onClick() and define the callback outside the onCreate()

for reference look into this link

public class MainActivity extends Activity implements SurfaceHolder.Callback {

    SurfaceView mSurfaceView;
    SurfaceHolder mSurfaceHolder;
    Camera mCamera;
    boolean mPreviewRunning;
    Button btncapture;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btncapture=(Button) findViewById(R.id.btncapture);
        mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        btncapture.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //take picture here
                mCamera.takePicture(null, null, mPictureCallback);
            }
        });
    }

    Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] imageData, Camera c) {

            Bitmap bitmap = BitmapFactory.decodeByteArray(imageData , 0, imageData .length);
            String file_path=saveToInternalSorage(bitmap);
            Toast.makeText(getApplicationContext(),"Image stored succesfully at "+file_path,Toast.LENGTH_LONG).show();
        }
    };

    private String saveToInternalSorage(Bitmap bitmapImage){
        ContextWrapper cw = new ContextWrapper(getApplicationContext());
         // path to /data/data/yourapp/app_data/imageDir
        File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
        // Create imageDir
        File mypath=new File(directory,"marina1.jpg");

        FileOutputStream fos = null;
        try {           

            fos = new FileOutputStream(mypath);

       // Use the compress method on the BitMap object to write image to the OutputStream
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return directory.getAbsolutePath();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mCamera=Camera.open();


    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int w,
            int h) {
        if (mPreviewRunning) {
            mCamera.stopPreview();
            }
            Camera.Parameters p = mCamera.getParameters();
            p.setPreviewSize(w, h);
            mCamera.setParameters(p);
            try {
            mCamera.setPreviewDisplay(holder);
            } catch (IOException e) {
            e.printStackTrace();
            }
            mCamera.startPreview();
            mPreviewRunning = true;

    }


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

    }

}