从我的应用程序拍照的功能不断使应用程序崩溃

时间:2020-09-14 22:08:24

标签: android kotlin mobile

我正在尝试实现一种目的,以启动相机应用程序,拍照并存储全尺寸图像。我正在[这里] [1]关注Google文档,但是每次我点击“拍照”按钮时,应用都会崩溃,并显示以下错误:

E / Android运行时:致命异常:主要 流程:com.example.pickmytrash,PID:7023 java.lang.IllegalArgumentException:未能找到包含/storage/emulated/0/Android/data/com.example.pickmytrash/files/Pictures/JPEG_20200914_224827_1183549578981134392.jpg 的已配置根目录 在androidx.core.content.FileProvider $ SimplePathStrategy.getUriForFile(FileProvider.java:744) 在androidx.core.content.FileProvider.getUriForFile(FileProvider.java:418) 在com.example.pickmytrash.ui.public_bins.PublicBinsFragment.getImage(PublicBinsFragment.kt:85) 在com.example.pickmytrash.ui.public_bins.PublicBinsFragment.access $ getImage(PublicBinsFragment.kt:25) 在com.example.pickmytrash.ui.public_bins.PublicBinsFragment $ onCreateView $ 3.onClick(PublicBinsFragment.kt:57) 在android.view.View.performClick(View.java:7448) 在android.view.View.performClickInternal(View.java:7425) 在android.view.View.access $ 3600(View.java:810) 在android.view.View $ PerformClick.run(View.java:28296) 在android.os.Handler.handleCallback(Handler.java:938) 在android.os.Handler.dispatchMessage(Handler.java:99) 在android.os.Looper.loop(Looper.java:223) 在android.app.ActivityThread.main(ActivityThread.java:7656) 在java.lang.reflect.Method.invoke(本机方法) 在com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run(RuntimeInit.java:592) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

这是我实现功能的Fragment类

package com.example.pickmytrash.ui.public_bins

import android.app.Activity.RESULT_OK
import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.pickmytrash.R
import java.io.File
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*

class PublicBinsFragment : Fragment(), AdapterView.OnItemSelectedListener {

    private lateinit var publicBinsViewModel: PublicBinsViewModel
    private lateinit var locationSpinner: Spinner
    private lateinit var binSpinner: Spinner
    private lateinit var imageButton: Button
    private lateinit var binImageView: ImageView
    private val PICTURE_RESULT_CODE = 20
    lateinit var currentPhotoPath: String

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        publicBinsViewModel = ViewModelProvider(this).get(PublicBinsViewModel::class.java)
        val root = inflater.inflate(R.layout.fragment_public_bins, container, false)
        publicBinsViewModel.text.observe(viewLifecycleOwner, Observer {
        })
        locationSpinner = root.findViewById(R.id.location_spinner)
        ArrayAdapter.createFromResource(
            requireContext(), R.array.location_entries,
            android.R.layout.simple_spinner_item
        )
            .also { locationAdapter ->
                locationAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                locationSpinner.adapter = locationAdapter}
        locationSpinner.onItemSelectedListener = this

        binSpinner = root.findViewById(R.id.spinner_bins)
        binImageView = root.findViewById(R.id.imageBin)
        imageButton = root.findViewById(R.id.btnAttachBin)
        imageButton.setOnClickListener { getImage() }
        return root
    }

    @Throws(IOException::class)
    private fun createImageFile(): File {
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
        val storageDir: File? = activity?.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        return File.createTempFile(
            "JPEG_${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
        ).apply {
            currentPhotoPath = absolutePath
        }
    }
    private fun getImage() {
       Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { pictureIntent ->
           activity?.packageManager?.let { it ->
               pictureIntent.resolveActivity(it)
               .also {
                   val photoFile: File? = try {
                       createImageFile()
                   } catch (ex: IOException) {
                       // Error occurred while creating the File
                       null
                   }
                   photoFile?.also {
                       val photoURI: Uri = FileProvider.getUriForFile(
                           requireActivity(),
                           "com.example.android.fileProvider",
                           it
                       )
                       pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                       startActivityForResult(pictureIntent, PICTURE_RESULT_CODE)
                   }
               }
           }
       }
    }

    private fun getBinArray(location: String) {
        when(location){
            "Wetheral Road" -> ArrayAdapter.createFromResource(
                requireContext(),
                R.array.wetheral_entries, android.R.layout.simple_spinner_item
            )
                .also { binsAdapter ->
                    binsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                    binSpinner.adapter = binsAdapter
                }

            "Douglas Road" -> ArrayAdapter.createFromResource(
                requireContext(),
                R.array.douglas_entries, android.R.layout.simple_spinner_item
            )
                .also { binsAdapter ->
                    binsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                    binSpinner.adapter = binsAdapter
                }

            "World Bank" -> ArrayAdapter.createFromResource(
                requireContext(),
                R.array.world_bank_entries, android.R.layout.simple_spinner_item
            )
                .also { binsAdapter ->
                    binsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                    binSpinner.adapter = binsAdapter
                }

            "Okigwe Road" -> ArrayAdapter.createFromResource(
                requireContext(),
                R.array.okigwe_road_entries, android.R.layout.simple_spinner_item
            )
                .also { binsAdapter ->
                    binsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                    binSpinner.adapter = binsAdapter
                }

            "PH Road" -> ArrayAdapter.createFromResource(
                requireContext(),
                R.array.ph_road_entries, android.R.layout.simple_spinner_item
            )
                .also { binsAdapter ->
                    binsAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
                    binSpinner.adapter = binsAdapter
                }
        }
    }

    override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
        val location = p0?.getItemAtPosition(p2).toString()
        getBinArray(location)
    }
    override fun onNothingSelected(p0: AdapterView<*>?) {
//        do nothing
    }

    private fun setPic() {
        // Get the dimensions of the View
        val targetW: Int = binImageView.width
        val targetH: Int = binImageView.height

        val bmOptions = BitmapFactory.Options().apply {
            // Get the dimensions of the bitmap
            inJustDecodeBounds = true

            val photoW: Int = outWidth
            val photoH: Int = outHeight

            // Determine how much to scale down the image
            val scaleFactor: Int = Math.max(1, Math.min(photoW / targetW, photoH / targetH))

            // Decode the image file into a Bitmap sized to fill the View
            inJustDecodeBounds = false
            inSampleSize = scaleFactor
            inBitmap
        }
        BitmapFactory.decodeFile(currentPhotoPath, bmOptions)?.also { bitmap ->
            binImageView.setImageBitmap(bitmap)
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICTURE_RESULT_CODE && resultCode == RESULT_OK) {
            setPic()
        }
    }
}

我的清单文件在下面

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

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.android.fileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>

</manifest>

这是我的布局文件。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.public_bins.PublicBinsFragment">

    <TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        android:fontFamily="@font/playfair_display_sc_black"
        android:text="@string/select_bin"
        android:textAlignment="center"
        android:textColor="@android:color/black"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Spinner
        android:id="@+id/location_spinner"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:entries="@array/location_entries"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Spinner
        android:id="@+id/spinner_bins"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/location_spinner" />

    <ImageView
        android:id="@+id/imageBin"
        android:layout_width="0dp"
        android:layout_height="240dp"
        android:layout_marginStart="32dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="32dp"
        android:src="@drawable/residential_recycling"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/spinner_bins" />

    <Button
        android:id="@+id/btnAttachBin"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="32dp"
        android:background="@drawable/rounded_btn"
        android:fontFamily="@font/playfair_display_sc_black"
        android:text="@string/attach_bin"
        android:textColor="@color/white"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageBin" />

    <Button
        android:id="@+id/reportBin"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="32dp"
        android:background="@drawable/rounded_btn"
        android:fontFamily="@font/playfair_display_sc_black"
        android:text="@string/send_report"
        android:textColor="@color/white"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnAttachBin" />
</androidx.constraintlayout.widget.ConstraintLayout>

请我需要帮助 [1]:https://developer.android.com/training/camera/photobasics#kotlin

0 个答案:

没有答案
相关问题