如何获取 CameraControl 和 CameraInfo

How to get CameraControl and CameraInfo

我是初级 Android 开发人员。 我使用的是 CameraX 的最新版本 (alpha08)。

我正在尝试设置缩放功能,为此我需要 CameraControl。 要获得 CameraControl,我需要一个 Camera 实例 -> Camera.getCameraControl() 根据 https://developer.android.com/reference/androidx/camera/core/CameraControl

我似乎无法获取 Camera 的实例。如果我尝试实例化 Camera,它会要求我实现 getCameraControl() 和 getCameraInfo(),它们都 return null.

谁能告诉我怎么做?

这是我的 ApplicationClass 文件

public class ApplicationClass extends Application implements CameraXConfig.Provider {

    @NonNull
    @Override
    public CameraXConfig getCameraXConfig() {
        return Camera2Config.defaultConfig();
    }
}

我的 startCamera() 函数进入我的 CameraActivity

private void startCamera() {

        CameraSelector mCameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

        mFlashToggle.setVisibility(View.VISIBLE);
        mGalleryFAB.setVisibility(View.VISIBLE);
        mTakePhotoFAB.setVisibility(View.VISIBLE);

        Point mSize = new Point();
        Display mDisplay = getWindowManager().getDefaultDisplay();

        mDisplay.getSize(mSize);
        int mWidth = mSize.x;
        int mHeight = mSize.y;

        Preview mPreview = new Preview.Builder()
                .setTargetResolution(new Size(mWidth, mHeight))
                .build();

        mPreview.setPreviewSurfaceProvider(mCameraPP.getPreviewSurfaceProvider());

        ImageCapture mImageCapture = new ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .setTargetRotation(getWindowManager().getDefaultDisplay().getRotation())
                .setTargetResolution(new Size(mWidth, mHeight))
                .build();


        // FLASHLIGHT PART
        mFlashToggle.getBackground().setAlpha(0);

        mFlashToggle.setOnClickListener(new View.OnClickListener() {
            boolean mIsActivated = true;

            @Override
            public void onClick(View v) {
                if (mIsActivated) {
                    mImageCapture.setFlashMode(ImageCapture.FLASH_MODE_ON);
                    mFlashToggle.setColorFilter(getResources().getColor(R.color.conforme));
                    mFlashToggle.getBackground().setAlpha(0);
                    mIsActivated = false;
                } else {
                    mImageCapture.setFlashMode(ImageCapture.FLASH_MODE_OFF);
                    mFlashToggle.setColorFilter(getResources().getColor(R.color.black));
                    mFlashToggle.getBackground().setAlpha(0);
                    mIsActivated = true;
                }
            }
        });

        // CLICK ON TAKE PHOTO BUTTON TRIGGERS THIS
        mTakePhotoFAB.setOnClickListener(view -> {
            mDir = new File(getExternalCacheDir(), "PhotosAuthentifier");
            boolean success = true;

            if (!mDir.exists()) {
                success = mDir.mkdir();
            }

            if (success) {
                File mFile = new File(mDir, new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(new Date()) + ".jpg");

                mImageCapture.takePicture(mFile, command -> new Thread(command).start(),
                        new ImageCapture.OnImageSavedCallback() {
                            @Override
                            public void onImageSaved(@NonNull File file) {
                                runOnUiThread(() -> {
                                    // ADD PHOTO INTO FINAL TAB
                                    mListOfPhotos.add(file.getAbsolutePath());

                                    // UPDATE PREVIEW OF PHOTOS ON SCREEN
                                    mAdapter.setmListOfPhotos(mListOfPhotos);
                                    mRecyclerView.setAdapter(mAdapter);

                                    if (mListOfPhotos.size() < 3) {
                                        actualNumberOfPhoto();
                                    } else {
                                        actualNumberOfPhoto();
                                    }
                                });

                            }

                            @Override
                            public void onError(int imageCaptureError, @NonNull String message, @Nullable Throwable cause) {
                                String mMessage = "Photo capture failed: " + message;
                                Toast.makeText(CameraActivity.this, mMessage, Toast.LENGTH_SHORT).show();

                                assert cause != null;
                                cause.printStackTrace();
                            }

                        });
            }

        });

        // CLICK ON SEND BUTTON TRIGGERS THIS
        mSendPhotoFAB.setOnClickListener(view -> {
            if (mSendPhotoFAB.isClickable()) {
                mSendPhotoFAB.setClickable(false);
                AlertDialog.Builder mAlertDialogBuilder = new AlertDialog.Builder(CameraActivity.this);

                String mMessage = null;


                if (sIDDemande == 0) {
                    LayoutInflater mInflater = this.getLayoutInflater();
                    View mDialogView = mInflater.inflate(R.layout.activity_camera_parameters, null);

                    // Parameters initialization
                    mDescriptionET = mDialogView.findViewById(R.id.activityCameraParametersDescriptionET);
                    mLanguageSpinner = mDialogView.findViewById(R.id.activityCameraSpecimenLanguageSpinner);
                    mMarkerYesButton = mDialogView.findViewById(R.id.activityCameraMarkerYesButton);
                    mMarkerNoButton = mDialogView.findViewById(R.id.activityCameraMarkerNoButton);
                    mMarkerInfoIB = mDialogView.findViewById(R.id.activityCameraMarkerInfoIB);
                    TextView mMarkerTV = mDialogView.findViewById(R.id.activityCamera15CreditTV);
                    TextView mMarkerInfoTV = mDialogView.findViewById(R.id.activityCameraMarkerInfoTV);
                    mSerialNumberET = mDialogView.findViewById(R.id.activityCameraSerialNumberET);
                    mModelNameET = mDialogView.findViewById(R.id.activityCameraModelNameET);

                    mAlertDialogBuilder.setView(mDialogView);

                    // OPTIONAL PARAMETERS FORM
                    if (sIDDemande == 0) {
                        ArrayAdapter<String> mSpinnerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item);
                        mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

                        mLanguageSpinner.setAdapter(mSpinnerAdapter);
                        mSpinnerAdapter.add(getResources().getString(R.string.french));
                        mSpinnerAdapter.add(getResources().getString(R.string.english));

                        mSpinnerAdapter.notifyDataSetChanged();

                        //To make Description part scrollable
                        mDescriptionET.setOnTouchListener((v, event) -> {
                            if (mDescriptionET.hasFocus()) {
                                v.getParent().requestDisallowInterceptTouchEvent(true);

                                if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_SCROLL) {
                                    v.getParent().requestDisallowInterceptTouchEvent(false);
                                    return true;
                                }
                            }

                            return false;
                        });

                        // Default specimen language is defined according to app language
                        String mLanguage = LocaleHelper.getLanguage(this).getString(LocaleHelper.SELECTED_LANGUAGE, null);

                        if (mLanguage != null) {
                            if (mLanguage.equals("fr")) {
                                mLanguageSpinner.setSelection(0);
                            } else if (mLanguage.equals("en")) {
                                mLanguageSpinner.setSelection(1);
                            }
                        }

                        mMarkerInfoIB.setOnClickListener(v -> {
                            if (!mMarkerInfoIsClicked) {
                                mMarkerInfoTV.setVisibility(View.VISIBLE);
                                mMarkerInfoIsClicked = true;
                            } else {
                                mMarkerInfoTV.setVisibility(View.GONE);
                                mMarkerInfoIsClicked = false;
                            }
                        });

                        mMarkerNoButton.setBackgroundColor(getResources().getColor(R.color.authentifier));
                        mMarkerYesButton.setBackgroundColor(getResources().getColor(R.color.text_color));

                        mMarkerYesButton.setOnClickListener(v -> {
                            if (!mMarkerYesClicked) {
                                mMarkerYesButton.setBackgroundColor(getResources().getColor(R.color.authentifier));
                                mMarkerNoButton.setBackgroundColor(getResources().getColor(R.color.text_color));
                                mMarkerTV.setVisibility(View.VISIBLE);
                                mMarkerYesClicked = true;
                            }
                        });

                        mMarkerNoButton.setOnClickListener(v -> {
                            if (mMarkerYesClicked) {
                                mMarkerNoButton.setBackgroundColor(getResources().getColor(R.color.authentifier));
                                mMarkerYesButton.setBackgroundColor(getResources().getColor(R.color.text_color));
                                mMarkerTV.setVisibility(View.GONE);
                                mMarkerYesClicked = false;
                            }
                        });

                        if (mAlertDialog != null) {
                            Objects.requireNonNull(mAlertDialog.getWindow()).setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
                        }
                    }
                }

                if (sIDDemande != 0) {
                    mMessage = getResources().getString(R.string.validationBeforePursue);
                }

                mAlertDialogBuilder
                        .setTitle(R.string.activityCameraParametersTitle)
                        .setCancelable(false)
                        .setMessage(mMessage)
                        .setPositiveButton(R.string.yes, (dialog, which) -> {
                            ((AlertDialog) dialog).getButton(which).setClickable(false);
                            dialog.dismiss();

                            if (sIDDemande != 0) {
                                new AsyncTaskSendComplementaryPhotos(sCameraActivity, sCameraActivity.getApplicationContext()).execute();
                            } else {
                                if (mDescriptionET.getText() != null && !mDescriptionET.getText().toString().equals("")) {
                                    mMapApplication.put(ConstantsClass.APPLICATION_DESCRIPTION, mDescriptionET.getText().toString());
                                }

                                if (mSerialNumberET.getText() != null && !mSerialNumberET.getText().toString().equals("")) {
                                    mMapApplication.put(ConstantsClass.SERIAL_NUMBER, mSerialNumberET.getText().toString());
                                }

                                if (mModelNameET.getText() != null && !mModelNameET.getText().toString().equals("")) {
                                    mMapApplication.put(ConstantsClass.MODEL_NAME, mModelNameET.getText().toString());
                                }

                                String mSpinnerValue = mLanguageSpinner.getSelectedItem().toString();

                                if (mSpinnerValue.equals("French")) {
                                    mSpinnerValue = "Français";
                                }

                                if (mSpinnerValue.equals("English")) {
                                    mSpinnerValue = "Anglais";
                                }

                                mMapApplication.put(ConstantsClass.LANGUAGE_SPECIMEN, mSpinnerValue);

                                if (mMarkerYesClicked) {
                                    mMapApplication.put(ConstantsClass.MARKER, "OUI");
                                } else {
                                    mMapApplication.put(ConstantsClass.MARKER, "NON");
                                }

                                new AsyncTaskSendData(sCameraActivity).execute();
                            }
                        })
                        .setNegativeButton(R.string.no, (dialogInterface, i) -> {
                            dialogInterface.dismiss();
                            mSendPhotoFAB.setClickable(true);
                        });

                mAlertDialog = mAlertDialogBuilder.create();

                mAlertDialog.show();
            } else {
                Toast mToast = Toast.makeText(this, getResources().getString(R.string.waitingMessageBeforeParameters), Toast.LENGTH_LONG);
                View mToastView = mToast.getView();

                mToastView.setBackgroundColor(getResources().getColor(R.color.authentifier));
                mToast.setGravity(Gravity.CENTER, 0, 0);

                mToast.show();
            }
        });

        // CLICK ON GALLERY BUTTON TRIGGERS THIS
        mGalleryFAB.setOnClickListener(view -> {
            checkPermissions();

            if (mPermission) {
                Intent mIntentGallery = new Intent(Intent.ACTION_PICK);
                mIntentGallery.setType("image/*");
                startActivityForResult(mIntentGallery, GALLERY_REQUEST);
            }

        });

        ImageAnalysis mAnalysis = new ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .build();

        mCameraProviderFuture.addListener(() -> {
            try {
                mCameraProvider = mCameraProviderFuture.get();
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
            }
            assert mCameraProvider != null;
            mCameraProvider.bindToLifecycle(sCameraActivity, mCameraSelector, mPreview, mAnalysis, mImageCapture);
        }, ContextCompat.getMainExecutor(this));
    }

您将获得 androidx.camera.core.Camera 个实例,这是在您的方法结束时调用 mCameraProvider.bindToLifecycle(sCameraActivity, mCameraSelector, mPreview, mAnalysis, mImageCapture); 的结果。

示例

private Camera camera;

camera = mCameraProvider.bindToLifecycle(sCameraActivity, mCameraSelector, mPreview, mAnalysis, mImageCapture);

然后,当您需要访问Camera的CameraControl或CameraInfo时,只需使用:

camera.getCameraControl()
camera.getCameraInfo()