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

Android相机拍照后无法在ImageView显示问题求助

问题根源与修复方案

你这代码里有几个关键问题导致拍的照片显示不出来:

  1. 直接用ACTION_IMAGE_CAPTURE时,相机不会通过data?.data返回图片Uri,默认只给个小缩略图在data.getParcelableExtra("data")里,而且你没处理这种情况;要拿全尺寸照片,必须提前指定输出文件的Uri。
  2. 没申请相机权限——拍照必须要CAMERA权限,你只加了存储权限,高版本Android(13+)还得适配新的权限规则。
  3. onActivityResult里没判断请求码和结果码,比如没确认是不是相机的请求、拍照有没有成功(RESULT_OK)。
  4. Android 7.0+不能直接用file:// Uri传文件给相机,得用FileProvider生成content://格式的Uri。

下面一步步改:

1. 先改Manifest配置

加相机权限,配好FileProvider:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- 拍照必须的相机权限 -->
    <uses-permission android:name="android.permission.CAMERA" />
    <!-- Android 12及以下需要的存储权限,13+不用了 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

    <!-- 声明依赖相机硬件 -->
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.LightningsDetection"
        tools:targetApi="31">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- 配置FileProvider,用于Android 7.0+的文件共享 -->
        <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>

    </application>

</manifest>

2. 建FileProvider的路径配置文件

在res目录下新建xml文件夹,再创建file_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 把照片存在应用私有目录的Pictures文件夹,不用申请存储权限也能访问 -->
    <external-files-path name="my_images" path="Pictures" />
</paths>

3. 重写MainActivity代码

补全权限申请、相机调用、照片显示的逻辑:

package com.example.lightningsdetection

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Environment
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

class MainActivity : AppCompatActivity() {

    private lateinit var capturedImageView: ImageView
    private var photoUri: Uri? = null
    private val REQUEST_CAMERA_PERMISSION = 100
    private val REQUEST_IMAGE_CAPTURE = 200

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        capturedImageView = findViewById(R.id.capturedImageView)

        val openCameraButton = findViewById<Button>(R.id.openCameraButton)
        openCameraButton.setOnClickListener {
            // 先检查权限再开相机
            checkCameraPermission()
        }
    }

    // 检查相机权限,没有就申请
    private fun checkCameraPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.CAMERA),
                REQUEST_CAMERA_PERMISSION
            )
        } else {
            openCamera()
        }
    }

    // 处理权限申请结果
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                openCamera()
            }
        }
    }

    // 打开相机,指定照片存储的Uri
    private fun openCamera() {
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        // 创建存储照片的文件
        val photoFile = try {
            createImageFile()
        } catch (e: Exception) {
            null
        }

        photoFile?.also {
            // 用FileProvider生成合法的Uri
            photoUri = FileProvider.getUriForFile(
                this,
                "${packageName}.fileprovider",
                it
            )
            // 告诉相机把照片存在这个Uri里
            intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
            if (intent.resolveActivity(packageManager) != null) {
                startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
            }
        }
    }

    // 创建唯一命名的图片文件,存在应用私有目录
    private fun createImageFile(): File {
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        return File.createTempFile(
            "JPEG_${timeStamp}_",
            ".jpg",
            storageDir
        )
    }

    // 处理相机返回的结果
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        // 只处理相机请求且拍照成功的情况
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            photoUri?.let { uri ->
                // 加载图片时缩小尺寸,避免内存溢出
                val options = BitmapFactory.Options()
                options.inSampleSize = 4 // 缩小4倍,可根据需求调整
                val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(uri), null, options)
                capturedImageView.setImageBitmap(bitmap)
            }
        }
    }
}

关于Logcat日志的说明

你看到的那个日志不是错误,只是系统记录的Activity窗口销毁信息,和照片不显示没关系,修复上面的代码后就能正常显示照片了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:35:06