Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

12.2. 相机开发

https://developer.android.google.cn/codelabs/camerax-getting-started?hl=zh-cn#0

12.2.1. 页面布局

			
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.home.HomeFragment">

    <androidx.camera.view.PreviewView
        android:id="@+id/previewView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:id="@+id/captureButton"
        android:layout_width="110dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:layout_marginEnd="50dp"
        android:elevation="2dp"
        android:text="拍摄"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintEnd_toStartOf="@id/vertical_centerline" />

    <Button
        android:id="@+id/cameraSelectorButton"
        android:layout_width="110dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="50dp"
        android:layout_marginStart="50dp"
        android:elevation="2dp"
        android:text="前后镜头"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@id/vertical_centerline" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/vertical_centerline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".50" />
</androidx.constraintlayout.widget.ConstraintLayout>			
			
			

12.2.2. 相机逻辑功能

			
package cn.aigcsst.medical.ui.home;

import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.util.Size;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.util.concurrent.ExecutionException;

import cn.aigcsst.medical.R;
import cn.aigcsst.medical.databinding.FragmentHomeBinding;
import cn.aigcsst.medical.ui.gallery.GalleryFragment;

public class HomeFragment extends Fragment {
    private static final String TAG = HomeFragment.class.getSimpleName();

    private static final int REQUEST_CODE = 200;
    Preview preview = new Preview.Builder().build();
    boolean switchCameraFrontBack = true;
    ImageAnalysis imageAnalysis = new ImageAnalysis.Builder().setTargetResolution(new Size(1280, 720)).build();
    private FragmentHomeBinding binding;
    private ListenableFuture<ProcessCameraProvider> cameraProviderFuture;
    private ProcessCameraProvider cameraProvider;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        HomeViewModel homeViewModel =
                new ViewModelProvider(this).get(HomeViewModel.class);

        binding = FragmentHomeBinding.inflate(inflater, container, false);
        View root = binding.getRoot();

//        final TextView textView = binding.textHome;
//        homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
        binding.previewView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return false;
            }
        });


        return root;
    }


    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (cameraProvider != null) {
            cameraProvider.unbindAll();
        }

    }

    @Override
    public void onPause() {
        super.onPause();
        //出去的时候要释放相机资源
        if (cameraProvider != null) {
            cameraProvider.unbindAll();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
//        ListenableFuture<ProcessCameraProvider> processCameraProvider = ProcessCameraProvider.getInstance(this);
        cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext());

        binding.captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Shut");
                try {
                    ImageCapture imageCapture = new ImageCapture.Builder().setTargetRotation(requireView().getDisplay().getRotation()).build();
                    cameraProvider = cameraProviderFuture.get();

                    cameraProvider.bindToLifecycle(getViewLifecycleOwner(), CameraSelector.DEFAULT_FRONT_CAMERA, imageAnalysis, imageCapture);

//                cameraProviderFuture.bindToLifecycle(lifecycleOwner, cameraSelector, imageCapture, imageAnalysis, preview);
//                File file = new File(Environment.getExternalStorageDirectory() + "/" + System.currentTimeMillis() + ".png");
                    File file = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + System.currentTimeMillis() + ".jpg");
                    Log.d(TAG, file.getAbsolutePath());
                    ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(file).build();
//                    ScheduledExecutorService cameraExecutor = CameraXExecutors.mainThreadExecutor();

                    imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(requireContext()), new ImageCapture.OnImageSavedCallback() {
                                @Override
                                public void onImageSaved(ImageCapture.OutputFileResults outputFileResults) {
                                    // insert your code here.
                                    Toast.makeText(requireContext(), outputFileResults.getSavedUri().toString(), Toast.LENGTH_SHORT).show();
                                    Log.d(TAG, "onImageSaved: saved");
                                    GalleryFragment fragment = GalleryFragment.newInstance(outputFileResults.getSavedUri().toString());
                                    requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.nav_host_fragment_content_main, fragment).addToBackStack("HomeFragment").commit();
//                                    requireActivity().getSupportFragmentManager().beginTransaction()
//                                            .replace(R.id.nav_host_fragment_content_main, GalleryFragment.newInstance(outputFileResults.getSavedUri().toString()))
////                                            .addToBackStack("GalleryFragment")
//                                            .commit();
//                                    getView().findViewById(R.id.play_btn).setOnClickListener(v -> {
                                    cameraProvider.unbindAll();
//
//                                    Bundle bundle = new Bundle();
//                                    bundle.putString("image", outputFileResults.getSavedUri().toString());
//                                    Navigation.findNavController(requireView()).navigate(R.id.nav_gallery, bundle);
//                                    });

                                }

                                @Override
                                public void onError(@NonNull ImageCaptureException error) {
                                    // insert your code here.
                                    Log.d(TAG, "onImageSaved: saved" + error.getMessage());
                                }
                            }
                    );
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


        binding.cameraSelectorButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

//                CameraSelector cameraSelector = new CameraSelector.Builder()
//                        .requireLensFacing(CameraSelector.LENS_FACING_BACK)
//                        .build();
                CameraSelector cameraSelector;
                if (switchCameraFrontBack) {
                    cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
                    switchCameraFrontBack = false;
                } else {
                    cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;
                    switchCameraFrontBack = true;
                }
//                preview.setSurfaceProvider(binding.previewView.getSurfaceProvider());
                cameraProvider.unbindAll();
                Camera camera = cameraProvider.bindToLifecycle(getViewLifecycleOwner(), cameraSelector, preview);

            }
        });

        //回来的时候要重新绑定一下:
        cameraProviderFuture.addListener(() -> {
            try {
                cameraProvider = cameraProviderFuture.get();
//                Preview preview = new Preview.Builder().build();

//        CameraSelector cameraSelector = new CameraSelector.Builder()
////                .requireLensFacing(CameraSelector.LENS_FACING_BACK)
//                .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
//                .build();
                cameraProvider.unbindAll();
                CameraSelector cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;
                preview.setSurfaceProvider(binding.previewView.getSurfaceProvider());
                Camera camera = cameraProvider.bindToLifecycle(getViewLifecycleOwner(), cameraSelector, preview);

//                bindPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {
                // No errors need to be handled for this Future.
                // This should never be reached.
            }
        }, ContextCompat.getMainExecutor(requireContext()));
    }
}