其他分享
首页 > 其他分享> > 安卓后台静默拍照。

安卓后台静默拍照。

作者:互联网

最近项目中需要后台拍照 悄悄上传至后台。

public class MainActivity extends AppCompatActivity {

    private String[] cameraIdList;
    private CameraDevice.StateCallback cameraDeviceStateCallback;
    private TextureView mTextureView;
    private ImageReader mImageReader;
    private CameraCaptureSession.StateCallback cameraCaptureSessionStateCallback;
    private Handler mBackgroundHandler;
    private HandlerThread mBackgroundThread;
    private File mFile;
    private CaptureRequest.Builder mPreviewBuilder;
    private CaptureRequest mPreviewRequest;
    private CameraCaptureSession mCaptureSession;
    private CameraDevice mCameraDevice;


    /**
     * 初始化Thread
     */
    private void initThread() {
        mBackgroundThread = new HandlerThread("CameraBackground");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initThread();

        mFile = new File(getExternalFilesDir(null), "mTextureView.jpg");
        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
        try {
            cameraIdList = cameraManager.getCameraIdList();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        mTextureView = new TextureView(this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(100, 100);
        mTextureView.setLayoutParams(params);
        WindowManager.LayoutParams wl = new WindowManager.LayoutParams(200, 200, 0, 0, PixelFormat.TRANSPARENT);
        // flag 设置 Window 属性
        wl.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
        // type 设置 Window 类别(层级)
        wl.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        wl.gravity = Gravity.CENTER;
        mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
                if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }
                try {
                    mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG,/*maxImages*/7);
                    mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
                    cameraManager.openCamera(cameraIdList[1], cameraDeviceStateCallback, mBackgroundHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

            }
        });


        findViewById(R.id.tv1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                windowManager.addView(mTextureView, wl);
            }
        });


        cameraDeviceStateCallback = new CameraDevice.StateCallback() {
            @Override
            public void onOpened(@NonNull CameraDevice camera) {
                SurfaceTexture texture = mTextureView.getSurfaceTexture();
                //assert(texture != null);

                // We configure the size of default buffer to be the size of camera preview we want.
                texture.setDefaultBufferSize(mTextureView.getWidth(), mTextureView.getHeight());
                // This is the output Surface we need to start preview.
                Surface surface = new Surface(texture);
                try {
                    mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
                mPreviewBuilder.addTarget(surface);//预览时,是将Surface()作为目标
                try {
                    mCameraDevice = camera;
                    camera.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()), cameraCaptureSessionStateCallback, mBackgroundHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onDisconnected(@NonNull CameraDevice camera) {

            }

            @Override
            public void one rror(@NonNull CameraDevice camera, int error) {

            }
        };

        cameraCaptureSessionStateCallback = new CameraCaptureSession.StateCallback() {
            @Override
            public void onConfigured(@NonNull CameraCaptureSession session) {
                mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                        CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                mPreviewRequest = mPreviewBuilder.build();
                try {
                    session.setRepeatingRequest(mPreviewRequest, new CameraCaptureSession.CaptureCallback() {
                        @Override
                        public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                            super.onCaptureStarted(session, request, timestamp, frameNumber);
                            mCaptureSession = session;
                            CaptureRequest.Builder captureBuilder =
                                    null;
                            try {
                                captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                            captureBuilder.addTarget(mImageReader.getSurface());//拍照时,是将mImageReader.getSurface()作为目标

                            // Use the same AE and AF modes as the preview.
                            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                            captureBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                            // Orientation
                            int rotation = getWindowManager().getDefaultDisplay().getRotation();

                            CameraCaptureSession.CaptureCallback CaptureCallback
                                    = new CameraCaptureSession.CaptureCallback() {

                                @Override
                                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                                               @NonNull CaptureRequest request,
                                                               @NonNull TotalCaptureResult result) {
//                                    showToast("Saved: " + mFile);
                                    Toast.makeText(MainActivity.this, "图片拍照成功路径" + mFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
                                    //Log.d("customCarmeraActivity", mFile.toString());
//                                    unlockFocus();//恢复预览

                                    windowManager.removeView(mTextureView);
                                }
                            };

                            try {
                                mCaptureSession.stopRepeating();
                                mCaptureSession.abortCaptures();
                                mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    }, mBackgroundHandler);
                } catch (CameraAccessException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onConfigureFailed(@NonNull CameraCaptureSession session) {

            }
        };


    }

    private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
            //showToast("onImageAvailable: " );
            mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
        }
    };

    /**
     * Saves a JPEG {@link Image} into the specified {@link File}.
     */
    private static class ImageSaver implements Runnable {

        /**
         * The JPEG image
         */
        private final Image mImage;
        /**
         * The file we save the image into.
         */
        private final File mFile;

        ImageSaver(Image image, File file) {
            mImage = image;
            mFile = file;
        }

        @Override
        public void run() {
            ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(mFile);
                output.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                mImage.close();
                if (null != output) {
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

点击按钮之后弹出系统级别的弹出框,悄悄拍照后上传至后台。

标签:拍照,NonNull,安卓,private,public,静默,Override,new,void
来源: https://blog.csdn.net/qq77485042/article/details/117744969