調(diào)取系統(tǒng)相機(jī)并且不展示預(yù)覽界面

最近項目中需要在界面中點(diǎn)擊按鈕拍照,但不展示預(yù)覽界面(吐槽:什么鬼需求),本來以為比較簡單,但在實現(xiàn)時遇到幾個問題,在此記錄下

本人的實現(xiàn)思路是將預(yù)覽界面的大小設(shè)置為一個寬高都為1px的界面就可以了
一開始的代碼

Camera camera;
    private void takePhoto(){

        if (camera == null)
            camera  = Camera.open();
        if (camera != null) {
            SurfaceView surfaceView = new SurfaceView(this);
            //設(shè)置預(yù)覽
            try {
                camera.setPreviewDisplay(surfaceView.getHolder());
            } catch (IOException e) {
                e.printStackTrace();
            }
            camera.startPreview();
            camera.takePicture(null, null, new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    try {
                        File file = getFile();
                        if (file == null) {
                            return;
                        }
                        FileOutputStream fos = new FileOutputStream(file);
                        fos.write(data);
                        fos.close();
                        Log.e("PhotoHandler", "圖片保存完成");
                    } catch (Exception error) {
                        error.printStackTrace();
                    }
                    camera.stopPreview();
                }
            });
        }
    }
    private String FILE_PATH = Environment
            .getExternalStorageDirectory().getAbsolutePath()
            + "/testImage/";
    private File getFile() {
        File f = new File(FILE_PATH);
        if (!f.exists()) {
           f.mkdirs();
        }

        String timeStamp = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss").format(new Date());
        File file;
        file = new File(FILE_PATH,
                "IMG_" + timeStamp + ".jpg");
        try {
            if (!file.exists()) {
                file.createNewFile();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

報錯:Caused by: java.lang.RuntimeException: takePicture failed

百度了下找到解決方法
問題是在相機(jī)實例上開始預(yù)覽后,需要一些時間才能拍照

camera.startPreview();
        camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                camera.takePicture(null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
               // do something you want with your picture and stop preview
                        camera.stopPreview();
                    }
                });

將takePicture方法放在setOneShotPreviewCallback回調(diào)中解決問題

又遇見問題 調(diào)用后沒反應(yīng),回調(diào)中也沒走
后來發(fā)現(xiàn)是SurfaceView 問題,直接new的話就會有這個問題,在xml文件中聲明就沒有問題(暫時不知道原因,哪位大佬知道麻煩告知,謝謝)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">
    <SurfaceView
        android:id="@+id/sview"
        android:layout_width="1px"
        android:layout_height="1px"/>

    <ImageView
        android:layout_margin="5dp"
        android:id="@+id/button"
        android:layout_centerInParent="true"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="@mipmap/ic_launcher_round"/>
</RelativeLayout>


Camera camera;
private SurfaceView surfaceview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        surfaceview = findViewById(R.id.sview);
        ImageView button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                takePhoto();
            }
        });
    }
    private void takePhoto(){

        if (camera == null)
            camera  = Camera.open();
        if (camera != null) {
//            SurfaceView surfaceView = new SurfaceView(this);
            //設(shè)置預(yù)覽
            try {
                camera.setPreviewDisplay(surfaceview.getHolder());
            } catch (IOException e) {
                e.printStackTrace();
            }
          .......
        }
    }

最終實現(xiàn)需求

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容