一、调用系统相机:
- 清单文件配置
- 授权、打开相机
- 获取照片
- 注意事项
1、清单文件配置
A、配置使用相机权限
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
B、provider配置
<provider
android:authorities="com.example.camera.fileprovider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/c"/>
C、meta-data标签:resource配置文件
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="my_images"
path="."/>
</paths>
2、授权打开系统相机:
A、打开页面授权:通过重写onRequestPermissionsResult方法获取授权结果。
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) !=
PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
requireActivity(),
arrayOf(Manifest.permission.CAMERA),
100
)
} else {
openCamera()
}
B、打开系统相机:下图中的imageUri是一个全局变量,是拍照成功后的图片 uri,拍照成功后在
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
方法中进行处理。
fun openCamera() {
val intent = Intent()
// 指定开启系统相机的Action
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE)
intent.addCategory(Intent.CATEGORY_DEFAULT)
// 根据文件地址创建文件
val file: File? = createImageFile()
if (file?.exists() == true) {
file?.delete()
}
// 把文件地址转换成Uri格式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
/*7.0以上要通过FileProvider将File转化为Uri*/
imageUri = file?.let {
FileProvider.getUriForFile(
requireContext(), "com.example.camera.fileprovider",
it
)
};
} else {
/*7.0以下则直接使用Uri的fromFile方法将File转化为Uri*/
imageUri = Uri.fromFile(file);
}
// 设置系统相机拍摄照片完成后图片文件的存放地址
// 设置系统相机拍摄照片完成后图片文件的存放地址
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(intent, 100)
}
注意:startActivityForResult() 是如果实在 Fragment中就不要使用 activity启动。
二、调用系统相机:
- 清单文件配置
- Camera自定义视图、工具
- 使用
1、清单文件中只需要添加相应权限
<uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-permission android:name="android.permission.CAMERA" />
2、自定义SurfaceView相机预览
class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = CameraSurfaceView.class.getSimpleName();
private SurfaceHolder mSurfaceHolder;
public CameraSurfaceView(Context context) {
super(context);
init();
}
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CameraSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
CameraUtils.openFrontalCamera(CameraUtils.DESIRED_PREVIEW_FPS);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
CameraUtils.startPreviewDisplay(holder);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
CameraUtils.releaseCamera();
}
}
3、Camera工具,用来控制相机、获取照片
public class CameraUtils {
// 相机默认宽高,相机的宽度和高度跟屏幕坐标不一样,手机屏幕的宽度和高度是反过来的。
public static final int DEFAULT_WIDTH = 1280;
public static final int DEFAULT_HEIGHT = 720;
public static final int DESIRED_PREVIEW_FPS = 270;
private static int mCameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;
private static Camera mCamera;
private static int mCameraPreviewFps;
private static int mOrientation = 0;
/**
* 打开相机,默认打开后置相机
* @param expectFps
*/
public static void openFrontalCamera(int expectFps) {
if (mCamera != null) {
throw new RuntimeException("camera already initialized!");
}
Camera.CameraInfo info = new Camera.CameraInfo();
int numCameras = Camera.getNumberOfCameras();
// for (int i = 0; i < numCameras; i++) {
// Camera.getCameraInfo(i, info);
// if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
// mCamera = Camera.open(0);
// mCameraID = info.facing;
// break;
// }
// }
// 如果没有前置摄像头,则打开默认的后置摄像头
if (mCamera == null) {
mCamera = Camera.open();
mCameraID = Camera.CameraInfo.CAMERA_FACING_BACK;