先上效果图:
github地址:https://github.com/tp-yan/ASProjects/tree/master/Camera4NotSave
1. 声明相机权限以及注册相关Activity
<application
...
>
<activity
android:name=".MyCameraActivity"
android:theme="@style/AppTheme.NoActionBarFullScreen" />
<activity
android:name=".ShowMultiImageActivity"
android:theme="@style/AppTheme.NoActionBarFullScreen" />
</application>
<uses-permission android:name="android.permission.CAMERA" />
2. MainActivity
要处理的逻辑简单:
- 动态申请权限
- 打开相机
- 将相机返回图像数据显示
public class MainActivity extends AppCompatActivity {
public final int CAMERA_PERMISSION_REQUEST = 100; // 申请相机请求码
public static final int INTENT_MY_CAMERA = 209; // 启动MyCameraActivity请求码
private static final String TAG = "MainActivity";
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.image_view);
}
// 启动自定义相机
@Permission(value = {
Manifest.permission.CAMERA}, requestCode = CAMERA_PERMISSION_REQUEST)
public void startMyCamera(View view) {
startActivityForResult(new Intent(MainActivity.this,
MyCameraActivity.class), INTENT_MY_CAMERA);
Log.d(TAG, "startMyCamera success ");
}
// 取消权限申请
@PermissionCanceled()
private void permissionCancel(CancelInfo cancelInfo) {
Toast.makeText(this, "取消权限申请", Toast.LENGTH_SHORT).show();
}
// 拒绝权限申请
@PermissionDenied()
private void deny(DenyInfo denyInfo) {
Toast.makeText(this, "拒绝权限申请", Toast.LENGTH_SHORT).show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case INTENT_MY_CAMERA:
if (resultCode == RESULT_OK) {
// 将 相机拍摄传回的byte[] jpegData转为Bitmap再显示
byte[] jpegData = data.getByteArrayExtra("camera_data");
int orientation = MyUtils.getOrientation(jpegData);
Bitmap b = BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
if (orientation != -1) {
b = MyUtils.rotateBitmap(b, orientation);
}
imageView.setImageBitmap(b);
}
break;
}
}
}
注:动态权限申请,使用了 https://github.com/zincPower/JPermission 提供的库,请自行参考使用细节
布局文件activity_main.xml
,一个按钮+ImageView
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="startMyCamera"
android:text="启动自定义相机" />
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
3. MyCameraActivity:实现自定义相机
从MainActivity
跳转到此,MyCameraActivity需要完成的功能:
- 加载自定义相机预览组件
cameraPreview
,获得相机控制对象Camera
- 提供相机拍照回调的接口
Camera.PictureCallback
,相机拍照时会回调此接口,将图像数据传过来,接下来我们就可以对拍摄的图像数据进行任意操作了(也是在此决定是否将数据保存到本地) - 将图像数据压缩后传到
ShowMultiImageActivity
完成预览功能,并根据ShowMultiImageActivity
返回的结果决定是“重拍”还是“完成”拍摄
MyCameraActivity:
public class MyCameraActivity extends AppCompatActivity {
private static final String TAG = "MyCameraActivity";
private final int REQUEST_SHOW_CODE = 11; // 调用ShowMultiImageActivity请求码
private int QUALITY = 60;
/**
* Camera类用于管理和操作camera资源,它提供了完整的相机底层接口,支持相机资源切换,
* 可设置预览、拍摄尺寸,设定光圈、曝光、聚焦等相关参数,获取预览、拍摄帧数据等功能
* 注:预览≠拍摄
*/
private Camera camera; // 代表相机对象
private Button takePhoto;
private CameraPreview cameraPreview; // 相机预览组件
private byte[] jpegData; // 保存相机拍摄的照片数据
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_camera); // 自定义相机显示界面
initViews();
}
private void initViews() {
takePhoto = (Button) findViewById(R.id.take_photo);
FrameLayout frameLayout = (FrameLayout) findViewById(R.id.surface_view);
cameraPreview = new CameraPreview(this);
camera = cameraPreview.getCamera();
frameLayout.addView(cameraPreview);
// 设置自动对焦
cameraPreview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
camera.autoFocus(null);
}
});
// 点击拍照
takePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public