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

Android 9(API 28)调用TakePicture拍照时相机停止运行如何解决?

问题根因

你代码的核心错误是调用ActivityResultContracts.TakePicture()启动相机时,传入了null作为照片存储的目标Uri。系统相机获取到空的输出路径后,无法保存拍摄结果,才触发了空指针异常崩溃。由于崩溃发生在系统相机进程而非你的应用进程,所以最初在你应用的日志面板中无法抓到堆栈。

你后续抓取的com.android.camera2进程日志也验证了这一点:相机在保存照片的环节尝试对传入的Uri做非空检查失败,直接抛出了空指针异常。

修复方案

Android 7.0及以上版本禁止直接使用本地文件路径跨应用传递,需要通过FileProvider生成合法的Content Uri提供给相机使用,完整修复步骤如下:

  • 第一步:配置FileProvider(未配置过的前提下)
    先在AndroidManifest.xml的<application>标签内添加provider配置:
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
    
    再在res/xml目录下创建file_paths.xml文件,配置允许共享的文件路径:
    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- 配置应用专属图片目录为可共享路径 -->
        <external-files-path name="profile_images" path="Pictures" />
    </paths>
    
  • 第二步:修改拍照逻辑,提前生成合法存储Uri
    调整后的代码如下:
    fun initCameraClick(activity: UserProfileActivity) {
        var uri: Uri? = null
        val takePicture = activity.registerForActivityResult(ActivityResultContracts.TakePicture()) { success: Boolean ->
            if (success) {
                uri?.let {
                    Log.i("camerauri", it.toString())
                    this.profilepic.setImageURI(it)
                }
            }
        }
        this.cameraButton.setOnClickListener {
            // 生成存储照片的本地文件
            val photoFile = File(
                activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES),
                "profile_${System.currentTimeMillis()}.jpg"
            )
            // 通过FileProvider生成合法的Content Uri
            uri = FileProvider.getUriForFile(
                activity,
                "${activity.packageName}.fileprovider",
                photoFile
            )
            // 传入非空Uri启动相机
            takePicture.launch(uri)
        }
    }
    
  • 第三步:检查权限配置
    在AndroidManifest.xml中添加必要的相机权限声明:
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- 若应用不强制要求设备有相机,设置required为false -->
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:06:03