Android Kotlin: фотографии, сохраненные с помощью EXTRA_OUTPUT, имеют размер 0 байт. - PullRequest
0 голосов
/ 11 марта 2020

Я следовал документации android на фотографиях (https://developer.android.com/training/camera/photobasics#kotlin), чтобы попытаться сделать фотографию и сохранить ее. Если я не использую EXTRA_OUTPUT, я могу успешно получить маленькое изображение из data.extra, но мне нужна большая картинка. Используя extra_output так же, как они делают в этой ссылке, я никогда не получаю реальную сохраненную фотографию, только 0-байтовые файлы. Что-то не так с моим extra_output, но я понятия не имею, что. Любые идеи?

Я нашел других людей с похожими проблемами, но не нашел реального решения

class CameraFragment2 : Fragment() {

    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.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                    takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_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
    }

}

в моем манифесте:

<provider
            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

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path
        name="my_images"
        path="." />
</paths>

1 Ответ

0 голосов
/ 11 марта 2020

Ваша основная ошибка в том, что вы не добавили FLAG_GRANT_WRITE_URI_PERMISSION в Intent. Вы предоставили выбранному пользователю доступ к приложению камеры для чтения, но не для записи. Таким образом, приложение камеры не может записать в указанное вами место.

Кроме того:

  • Вы потеряете значение currentPhotoPath, если ваш процесс будет прерван, пока камера приложение находится на переднем плане, что происходит довольно редко

  • Вы также можете рассмотреть возможность очистки provider_paths.xml (у вас есть две конфликтующие записи)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...