Remarques sur l'appareil photo Android

1. Comment utiliser l'appareil photo
  1. Caméra du système d'appel
  2. Caméra personnalisée
2. Appelez la caméra système

1. Appelez la caméra système et renvoyez les vignettes

	public static final int REQUEST_CODE = 0x001;
    private ImageView ivPic;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivPic = findViewById(R.id.iv_pic);
    }

    public void invokeSystemCamera(View view) {
    
    
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);  // 1.使用到的Action
        startActivityForResult(intent, REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    
     // data返回的是缩略图,防止数据过大导致内存溢出
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
    
    
            if (data != null) {
    
    
                Bundle bundle = data.getExtras();
                Bitmap bitmap = (Bitmap) bundle.get("data"); // 2.获取缩略图
                ivPic.setImageBitmap(bitmap);
            }
        }
    }

2. Appelez la caméra système et renvoyez l'image originale.
Spécifiez le chemin de sauvegarde de l'image via Uri. Celui-ci doit être compatible 7.0, sinon une erreur sera signalée. (L'autorisation WRITE_EXTERNAL_STORAGE est requise ici)

    public static final int REQUEST_CODE2 = 0x002;
    public static final int PERMISSION_REQUEST_CODE = 0x003;
    private ImageView ivPic;
    private String imagePath = Environment.getExternalStorageDirectory() + File.separator + "temp.jpg"; 
    private File imageFile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivPic = findViewById(R.id.iv_pic);
        imageFile = new File(imagePath); // 1.设置图片保存路径
        requestPermission(); // 要使用到WRITE_EXTERNAL_STORAGE权限
    }

    private void requestPermission() {
    
    
        ArrayList<String> permissionList = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    
    
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if (permissionList.size() > 0) {
    
    
            String[] permissions = new String[permissionList.size()];
            permissionList.toArray(permissions);
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
        }
    }

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

    public void invokeSystemCamera2(View view) {
    
    
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Uri uri;
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
    
     // 7.0以下系统使用文件的Uri
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            uri = Uri.fromFile(imageFile); // 7.0 使用此方式会报Caused by: android.os.FileUriExposedException
        } else {
    
    
            uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".authority", imageFile); // 使用FileProvider兼容7.0及以上版本
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); // 2.通过uri告诉系统图片保存路径,这里的uri需要做兼容
        startActivityForResult(intent, REQUEST_CODE2);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    
    
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE2 && resultCode == RESULT_OK) {
    
    
            FileInputStream fileInputStream = null;
            try {
    
    
                fileInputStream = new FileInputStream(imageFile); // 3.将图片文件转换为流
                Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream); // 4.获取bitmap
                ivPic.setImageBitmap(bitmap);
            } catch (FileNotFoundException e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                try {
    
    
                    if (fileInputStream != null) {
    
    
                        fileInputStream.close();
                    }
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }

Configuration du fournisseur de fichiers d'AndroidManifest

		<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.lgf.camera.demo.authority"
            android:exported="false"
            android:grantUriPermissions="true" >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path" />
        </provider>

Configuration File_path de XML sous res :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="imagePath"
        path="/" />
</paths>

Utilisation du fournisseur de fichiers

3. Caméra personnalisée

Ceci est implémenté à l'aide de la classe android.hardware.Camera . Nous ne savons pas encore grand-chose sur Camera2 et CameraView.

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback {
    
    

    public static final int PERMISSION_REQUEST_CODE = 0x003;
    private Camera mCamera;
    private SurfaceView svCamera;
    private SurfaceHolder mSurfaceHolder;
    private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
    
    
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
    
     
        	// 处理图片数据
            File file = new File(Environment.getExternalStorageDirectory(), "temp.png");
            FileOutputStream fileOutputStream = null;
            try {
    
    
                fileOutputStream = new FileOutputStream(file);
                fileOutputStream.write(data);
            } catch (IOException e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                if (fileOutputStream != null) {
    
    
                    try {
    
    
                        fileOutputStream.close();
                    } catch (IOException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        svCamera = findViewById(R.id.sv_camera); // 1,获取SurfaceView对象
        mSurfaceHolder = svCamera.getHolder();
        mSurfaceHolder.addCallback(this); // 监听SurfaceView事件
        svCamera.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                mCamera.autoFocus(null); // 点击SurfaceView对焦,但是不回调
            }
        });
        requestPermission();
    }

    private void requestPermission() {
    
    
        ArrayList<String> permissionList = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    
    
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
    
    
            permissionList.add(Manifest.permission.CAMERA);
        }

        if (permissionList.size() > 0) {
    
    
            String[] permissions = new String[permissionList.size()];
            permissionList.toArray(permissions);
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
        }
    }

    private void setStartPreview(Camera camera, SurfaceHolder surfaceHolder) {
    
    
        try {
    
    
            camera.setDisplayOrientation(90); // 设置预览方向,否则会横屏显示
            camera.setPreviewDisplay(surfaceHolder);  // 3.关联Camera和SurfaceView,设置显示在SurfaceHolder
            camera.startPreview(); // 开始预览
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    @Override
    protected void onResume() {
    
    
        super.onResume();
        startPreview();
    }

    @Override
    protected void onPause() {
    
    
        super.onPause();
        releaseCamera(); // 释放Camera资源
    }

    private void startPreview() {
    
    
        createCamera();
        if (mSurfaceHolder != null) {
    
    
            setStartPreview(mCamera, mSurfaceHolder);
        }
    }

    private void createCamera() {
    
    
        if (mCamera == null) {
    
    
            mCamera = Camera.open(); // 2.创建Camera对象
        }
    }

    private void releaseCamera() {
    
    
        if (mCamera != null) {
    
    
            mCamera.setPreviewCallback(null); // 停止监听回调
            mCamera.stopPreview(); // 停止预览
            mCamera.release(); // 释放camera资源
            mCamera = null;
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    
     // 界面获取焦点时,回调
        Log.d("CameraActivity", "surfaceCreated");
        setStartPreview(mCamera, mSurfaceHolder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
     // 界面获取焦点时或SurfaceView大小改变时,回调
        Log.d("CameraActivity", "surfaceChanged");
        mCamera.stopPreview();
        setStartPreview(mCamera, mSurfaceHolder);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    
     // 界面失去焦点时,回调
        Log.d("CameraActivity", "surfaceDestroyed");
        releaseCamera();
    }

    /**
     * 此方法为点击事件
     * @param view
     */
    public void capture(View view) {
    
    
        // 设置参数
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureFormat(ImageFormat.JPEG); // 设置图片格式
        parameters.setPreviewSize(800, 400); // 设置图片大小
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        // 对焦,并获取对焦结果
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
    
    
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
    
    
                if (success) {
    
     // 对焦成功
                    mCamera.takePicture(null/*拍照时,会发出拍照的声音*/, null, pictureCallback);
                }
            }
        });
    }
}

**Remarques :** cycle de vie onResume, onPause, surfaceCreated, surfaceChanged, surfaceDestroyed

onResume->surfaceCreated->surfaceChanged->onPause->surfaceDestroyed

Guess you like

Origin blog.csdn.net/fengyulinde/article/details/94918703
Recommended