Android Kotlin:使用EXTRA_OUTPUT保存的照片为0字节

问题描述 投票:0回答:1

我已按照Android文档中的照片(https://developer.android.com/training/camera/photobasics#kotlin)尝试拍摄并保存照片。如果不使用EXTRA_OUTPUT,则可以从data.extra成功获取小图像,但是我需要更大的图片。使用extra_output的方式与在该链接中所做的方式相同,我从未保存过实际照片,仅保存了0个字节的文件。所以我的extra_output出了问题,但是我不知道是什么。有什么想法吗?

我确实找到了其他有类似问题,但没有实际解决方案的人


    private lateinit var binding: CameraFragment2FragmentBinding
    private lateinit var textRecognizer: TextRecognizer
    private lateinit var photoFile: File
    private lateinit var photoUri: Uri

    companion object {
        fun newInstance() = CameraFragment2()
    }

    private lateinit var viewModel: CameraFragment2ViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = CameraFragment2FragmentBinding.inflate(inflater)

        textRecognizer = TextRecognizer.Builder(context).build()

        dispatchTakePictureIntent()

        return binding.root
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(CameraFragment2ViewModel::class.java)
        // TODO: Use the ViewModel
    }

    private fun dispatchTakePictureIntent() {
        val packageManager = context!!.packageManager
        Intent(Intents.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
            // Ensure that there's a camera activity to handle the intent
            takePictureIntent.resolveActivity(packageManager)?.also {
                // Create the File where the photo should go
                val photoFile: File? = try {
                    createImageFile()
                } catch (ex: IOException) {
                    // Error occurred while creating the File
                    Log.wtf("creating file failed", "creating file failed")
                    null
                }
                // Continue only if the File was successfully created
                photoFile?.also {
                    val photoURI: Uri = FileProvider.getUriForFile(
                        context!!,
                        //BuildConfig.APPLICATION_ID + ".provider",
                        "com.example.myapplication.fileprovider",
                        it
                    )
                    takePictureIntent.putExtra(EXTRA_OUTPUT, photoURI)
                    takePictureIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                    startActivityForResult(takePictureIntent, 1)
                }
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        //super.onActivityResult(requestCode, resultCode, data)


        //val file = File(currentPhotoPath)

        //val bitmap = BitmapFactory.decodeFile(currentPhotoPath)

        //scan(bitmap)

        val filePathUri = Uri.parse(currentPhotoPath)
        val myFile = File(filePathUri.path)
        val file_size = (myFile.length() / 1024).toString().toInt()
        Log.wtf("path", currentPhotoPath)
        Log.wtf("size", file_size.toString())

        //val image = File(currentPhotoPath)
        val bmOptions = BitmapFactory.Options()
        bmOptions.inJustDecodeBounds = false
        bmOptions.inSampleSize = 4
        //var bitmap = BitmapFactory.decodeFile(image.absolutePath, bmOptions)
        //scan(bitmap)

        var thing: Bitmap

        BitmapFactory.decodeFile(currentPhotoPath, bmOptions)?.also { bitmap ->
            scan(bitmap)
            thing = bitmap
        }



        if (resultCode == Intents.RESULT_OK && requestCode == 1){
            //val photo = data!!.extras!!.get(EXTRA_OUTPUT) as Bitmap
            //scan(photo)
            //val bitmap = BitmapFactory.decodeFile(photoFile.absolutePath)

            //scan(bitmap)

        }
    }

    lateinit var currentPhotoPath: String

    @Throws(IOException::class)
    private fun createImageFile(): File {
        // Create an image file name
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val storageDir: File = context!!.getExternalFilesDir(Environment.DIRECTORY_PICTURES)!!
        return File.createTempFile(
            "JPEG_${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
        ).apply {
            // Save a file: path for use with ACTION_VIEW intents
            currentPhotoPath = absolutePath
        }
    }


    private fun scan(photo: Bitmap){
        //val intent = Intent(ACTION_IMAGE_CAPTURE)
        val imageFrame = Frame.Builder()
            .setBitmap(photo)
            .build()
        val detections = textRecognizer.detect(imageFrame)

        val builder = StringBuilder()
        if (detections.size() != 0){
            for (x in 0..detections.size()) {
                builder.append(detections[x].value)
                builder.append("\n")
            }
        }


        binding.camFragResult.text = builder
    }

}

在我的清单上:

            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.myapplication.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"></meta-data>
        </provider>

provider_paths.xml

<paths>
    <external-path
        name="external_files"
        path="." />
    <external-files-path
        name="my_images"
        path="Android/data/com.example.myapplication/files/Pictures" />
</paths>
android kotlin
1个回答
0
投票

您的主要错误是您没有将FLAG_GRANT_WRITE_URI_PERMISSION添加到Intent。您授予用户选择的相机应用程序读取权限,而不是写入权限。因此,相机应用无法写入您的指定位置。

另外:

  • 如果相机应用程序在前台运行时终止进程,则会丢失currentPhotoPath的值,这会发生很多

  • 您可能还会考虑清理provider_paths.xml(您有两个冲突的条目)

© www.soinside.com 2019 - 2024. All rights reserved.