简体   繁体   中英

Using the camera in android

I am trying to build an Android app that simply uses the camera to take a picture without launching the default camera app. In other words, I want to make a custom camera app. I can do this using the Camera hardware object class, however this is deprecated and I want to use some of the new features of camerax and not have to worry about the code not working after some time. I have also read the camera API documentation, however it is still unclear how to use the camera. Are there any very simple step by step tutorials or guides that might help me? Thanks,

You can check my example about how to use AndroidX libraries and TextureView for camera customization.

https://github.com/icerrate/Custom-Camera-App

First at all, define your layout. This is my activity_main.xml file:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextureView
        android:id="@+id/view_finder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/take_photo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_margin="@dimen/horizontal_margin"
        app:layout_constraintStart_toStartOf="parent"
        android:src="@drawable/ic_camera"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Remember that TextureView will receive the camera preview and the Floating Action Button works as a "Take Photo" button.

Then add your MainActivity.java file:

public class MainActivity extends AppCompatActivity implements LifecycleOwner {

    private static final int RC_PERMISSIONS = 100;

    private TextureView viewFinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        viewFinder = findViewById(R.id.view_finder);
        FloatingActionButton takePhotoFab = findViewById(R.id.take_photo);

        //Check permissions
        if (allPermissionGranted()) {
            viewFinder.post(new Runnable() {
                @Override
                public void run() {
                    startCamera();
                }
            });
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[] {Manifest.permission.CAMERA}, RC_PERMISSIONS);
        }

        takePhotoFab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                takePhoto();
            }
        });
    }

    private void startCamera() {
        Point screenSize = getScreenSize();
        int width = screenSize.x;
        int height = screenSize.y;

        //Get real aspect ratio
        DisplayMetrics displayMetrics = new DisplayMetrics();
        Display display = getWindowManager().getDefaultDisplay();
        display.getRealMetrics(displayMetrics);
        Rational rational = new Rational(displayMetrics.widthPixels, displayMetrics.heightPixels);

        //Build the camera preview
        PreviewConfig build = new PreviewConfig.Builder()
                .setTargetAspectRatio(rational)
                .setTargetResolution(new Size(width,height))
                .build();
        Preview preview = new Preview(build);

        preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {
            @Override
            public void onUpdated(Preview.PreviewOutput output) {
                ViewGroup group = (ViewGroup) viewFinder.getParent();
                group.removeView(viewFinder);
                group.addView(viewFinder, 0);

                viewFinder.setSurfaceTexture(output.getSurfaceTexture());
            }
        });

        CameraX.bindToLifecycle(this, preview);
    }

    private void takePhoto() {
        Toast.makeText(this, "Shot!",
                Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == RC_PERMISSIONS) {
            if (allPermissionGranted()) {
                viewFinder.post(new Runnable() {
                    @Override
                    public void run() {
                        startCamera();
                    }
                });
            } else {
                Toast.makeText(this, "Permission not granted",
                        Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    private boolean allPermissionGranted() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    }

    private Point getScreenSize() {
        Display display = getWindowManager(). getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return size;
    }
}

In this class, you would be able to send the camera preview to the TextureView , with help of PreviewConfig.Builder() and binding it to the Activity lifeCycle using CameraX.bindToLifeCycle()

Also, don't forget to add Camera permission to the manifest and consider runtime permissions.

Screenshot: Custom Camera preview

Hope this help you!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM