简体   繁体   English

如何在片段中显示相机?

[英]How to display camera in fragment?

I'm trying to access the camera within the fragment in android studio.我正在尝试访问 android studio 片段内的相机。 these are the codes I wrote My Fragment Codes:这些是我写的代码片段代码:

    package com.example.proje.ui.camera;

import android.hardware.Camera;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.example.proje.ui.camera.CameraViewModel;
import com.example.proje.R;

public class CameraFragment extends Fragment {


    Camera camera;
    FrameLayout frameLayout;
    ShowCamera showCamera;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.fragment_camera, container, false);

        return root;


   }
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);


        frameLayout = (FrameLayout)getActivity().findViewById(R.id.frameLayout);

        camera = Camera.open();

        showCamera = new ShowCamera(getContext(), camera);
        frameLayout.addView(showCamera);
    }
}

ShowCamera code:显示相机代码:

    package com.example.proje.ui.camera;

    import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;

public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback
{

    Camera camera;
    SurfaceHolder holder;
    public ShowCamera(Context context, Camera camera) {
        super(context);
        this.camera = camera;
        holder = getHolder();
        holder.addCallback(this);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Camera.Parameters params = camera.getParameters();

        if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE)
        {
            params.set("orientation", "portrait");
            camera.setDisplayOrientation(90);
            params.setRotation(90);
        }
        else
        {
            params.set("orientation", "landscape");
            camera.setDisplayOrientation(0);
            params.setRotation(0);
        }

        camera.setParameters(params);
        try
        {
            camera.setPreviewDisplay(holder);

            camera.startPreview();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

I gave the necessary permissions from the android manifest file.我从 android 清单文件中授予了必要的权限。 compiles seamlessly in android studio but when I run it on the phone I get the application stopped error.在 android studio 中无缝编译,但是当我在手机上运行它时,我得到应用程序停止错误。

How can I solve this problem?我怎么解决这个问题?

Below is a simple fragment that does the following:下面是一个简单的片段,它执行以下操作:

  1. requests permission to camera请求相机许可
  2. then opens the camera to take photo然后打开相机拍照
  3. resize it by width to 1200, saves it on SD card for later upload if needed将其按宽度调整为 1200,将其保存在 SD 卡上,以便以后需要时上传

It seems that you want only to open the camera in fragment, if so use only the needed code: openCameraIntent()似乎您只想在片段中打开相机,如果是这样,请仅使用所需的代码: openCameraIntent()

What you are trying to do is not possible (load the Camera inside FrameLayout).您尝试执行的操作是不可能的(在 FrameLayout 中加载相机)。
the camera should be opened using startActivityForResult since it's an Activity by itself.相机应该使用 startActivityForResult 打开,因为它本身就是一个活动。

package com.example.proje.ui.camera;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;

import static android.Manifest.permission.CAMERA;

public class CameraFragment extends Fragment {

    private final int PREFERED_IMAGE_WIDTH_SIZE = 1200;

    private final int CAMERA_PERMISSION_CODE = 300;
    private final int RESULT_CAMERA_LOAD_IMG = 1889;

    private FrameLayout frameLayout;
    private ImageView image_view;
    private Activity activity;

    private List<String> imagesFilesPaths = new ArrayList<>();

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        View root = inflater.inflate(R.layout.fragment_camera, container, false);

        return root;


    }
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        activity = getActivity();
        image_view = getActivity().findViewById(R.id.image_view);
        frameLayout = getActivity().findViewById(R.id.frameLayout);


        takePhotoFromCamera();
    }

    // THIS FUNCTION CAN BE CALLED WHENEVER YOU WANT TO TAKE NEW PHOTO
    private void takePhotoFromCamera(){
        if (ContextCompat.checkSelfPermission(Objects.requireNonNull(getContext()), CAMERA) != PackageManager.PERMISSION_GRANTED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                requestPermissions(new String[]{CAMERA}, CAMERA_PERMISSION_CODE);
            }
        } else  {
            openCameraIntent();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        if(requestCode == CAMERA_PERMISSION_CODE){
            if (permissions.length > 0 && grantResults.length > 0) {

                boolean flag = true;
                for (int grantResult : grantResults) {
                    if (grantResult != PackageManager.PERMISSION_GRANTED) {
                        flag = false;
                    }
                }
                if (flag) {
                    openCameraIntent();
                }
            }
        }else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    private void openCameraIntent(){
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if(cameraIntent.resolveActivity(Objects.requireNonNull(activity).getPackageManager()) != null){
            //Create a file to store the image
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
            }
            if (photoFile != null) {
                Uri photoURI = FileProvider.getUriForFile(Objects.requireNonNull(getContext()),"com.smartestmedia.camerainfragment.provider", photoFile);
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(cameraIntent, RESULT_CAMERA_LOAD_IMG);
            }
        }
    }

    private File createImageFile() throws IOException {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
        String imageFileName = "IMG_" + timeStamp + "_";
        File storageDir = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        imagesFilesPaths.add(image.getAbsolutePath());
        return image;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == RESULT_CAMERA_LOAD_IMG && resultCode == Activity.RESULT_OK){

            String tempImageFilePath = imagesFilesPaths.get(imagesFilesPaths.size()-1);

            Uri tempImageURI = Uri.fromFile(new File( tempImageFilePath ));

            resizeThanLoadImage(tempImageFilePath, tempImageURI);

        }

    }

    private void resizeThanLoadImage(String tempImageFilePath, Uri tempImageURI){
        Bitmap bitmap = null;
        try {
            bitmap = MediaStore.Images.Media.getBitmap(Objects.requireNonNull(activity).getContentResolver(), tempImageURI);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(bitmap == null)return;

        int sizeDivisor = 1;

        double imageSize = bitmap.getWidth();
        if(bitmap.getHeight() > bitmap.getWidth())imageSize = bitmap.getHeight();
        sizeDivisor = round(imageSize / PREFERED_IMAGE_WIDTH_SIZE);
        if(sizeDivisor == 0)sizeDivisor = 1;


        Bitmap bitmapScaled = Bitmap.createScaledBitmap(bitmap, (bitmap.getWidth()/sizeDivisor), (bitmap.getHeight()/sizeDivisor), true);

        storeBitmapInFile(bitmapScaled, tempImageFilePath);

        onImageLoaded(tempImageURI);
    }

    private int round(double d){
        double dAbs = Math.abs(d);
        int i = (int) dAbs;
        double result = dAbs - (double) i;
        if(result<0.5){
            return d<0 ? -i : i;
        }else{
            return d<0 ? -(i+1) : i+1;
        }
    }

    private void storeBitmapInFile(Bitmap image, String filePath) {
        File pictureFile = new File(filePath);
        String TAG = "TakePhotosFragment>>>> ";
        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            image.compress(Bitmap.CompressFormat.JPEG, 80, fos);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }

    private void onImageLoaded(Uri imageUri) {

        // LOAD YOUR IMAGE in imageview
        image_view.setImageURI(imageUri);
    }

}

Good Luck!祝你好运!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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