我正在尝试实现一种目的,以启动相机应用程序,拍照并存储全尺寸图像。我正在[这里] [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