You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过自定义按钮实现拍照?应用已打开相机需点击按钮触发拍照

我来帮你搞定这个拍照按钮的实现,结合你现有的代码,咱们一步步来:

实现相机拍照按钮功能的完整方案

1. 先补全布局与MainActivity核心逻辑

首先确保你的activity_main.xml里有拍照按钮:

<Button
    android:id="@+id/btn_capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="拍照"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"/>

然后完善MainActivity的代码,添加按钮点击事件和拍照回调逻辑:

public class MainActivity extends AppCompatActivity {
    private Camera mCamera = null;
    private CameraView mCameraView = null;
    private Button mCaptureBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Android 6.0+ 必须动态申请相机权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 100);
            return;
        }

        // 初始化相机实例
        try {
            mCamera = Camera.open();
        } catch (Exception e) {
            Log.d("ERROR", "Failed to get camera: " + e.getMessage());
            Toast.makeText(this, "相机初始化失败", Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        // 绑定自定义预览控件
        mCameraView = findViewById(R.id.camera_view);
        mCameraView.setCamera(mCamera);

        // 绑定拍照按钮并设置点击事件
        mCaptureBtn = findViewById(R.id.btn_capture);
        mCaptureBtn.setOnClickListener(v -> capturePhoto());
    }

    // 拍照核心方法
    private void capturePhoto() {
        if (mCamera == null) return;

        // 设置拍照回调:第三个参数是最终的图片数据回调
        mCamera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                // 将字节数组转为Bitmap
                Bitmap capturedBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                // 跳转到第二个Activity展示照片(或保存到本地)
                navigateToResultActivity(capturedBitmap);

                // 拍完恢复预览,避免相机画面卡住
                mCamera.startPreview();
            }
        });
    }

    // 跳转到结果页面
    private void navigateToResultActivity(Bitmap bitmap) {
        Intent intent = new Intent(this, ResultActivity.class);
        // 注意:大图片建议传文件路径而非直接传Bitmap,这里做简单演示
        intent.putExtra("captured_image", bitmap);
        startActivity(intent);
    }

    // 处理权限申请结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 100) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                recreate(); // 权限通过后重启页面初始化相机
            } else {
                Toast.makeText(this, "需要相机权限才能使用", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    // 释放相机资源,避免内存泄漏
    @Override
    protected void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 重新初始化相机
        if (mCamera == null && ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_GRANTED) {
            try {
                mCamera = Camera.open();
                mCameraView.setCamera(mCamera);
            } catch (Exception e) {
                Log.d("ERROR", "Failed to reopen camera: " + e.getMessage());
            }
        }
    }
}

2. 结果Activity(ResultActivity)实现

如果需要在第二个页面展示拍摄的照片,代码可以这样写:

public class ResultActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_result);

        ImageView imageView = findViewById(R.id.iv_captured);
        Bitmap bitmap = getIntent().getParcelableExtra("captured_image");
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
    }
}

对应的activity_result.xml布局:

<ImageView
    android:id="@+id/iv_captured"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scaleType="centerCrop"/>

3. 关键注意事项

  • 权限处理:Android 6.0及以上必须动态申请CAMERA权限,否则相机无法正常打开
  • 资源释放:在onPause方法中一定要释放相机资源,否则会导致内存泄漏,还会影响其他应用使用相机
  • 预览恢复:拍照完成后调用mCamera.startPreview(),让相机回到预览状态
  • 图片传输优化:如果拍摄的图片较大,建议先保存到本地,再传递文件路径给第二个Activity,避免出现OOM(内存溢出)问题

内容的提问来源于stack exchange,提问作者MKM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:19:33