Android ActivityResultContracts.TakePicture返回“无此类文件或目录”
在Fragment中,我尝试从相机中捕获一个图像并使用它。我想使用ActivityResultContracts.TakePicture进行拍摄,但当我在拍摄后尝试使用此图像时,我得到:Android ActivityResultContracts.TakePicture返回“无此类文件或目录”,android,kotlin,Android,Kotlin,在Fragment中,我尝试从相机中捕获一个图像并使用它。我想使用ActivityResultContracts.TakePicture进行拍摄,但当我在拍摄后尝试使用此图像时,我得到: W/ImageView: Unable to open content: content://com.myniprojects.pixagram/my_images/default_image.jpg java.io.FileNotFoundException: open failed: ENOENT
W/ImageView: Unable to open content: content://com.myniprojects.pixagram/my_images/default_image.jpg
java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
我见过这个问题,但我不知道我做错了什么。以下是我所做的一切:
我在清单中添加了以下内容:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.myniprojects.pixagram"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
碎片:
类AddFragment:FragmentR.layout.fragment\u add
{
私有lateinit var imagePath:文件
私有lateinit var newFile:File
私有lateinit变量uri:uri
覆盖视图上的乐趣CreatedView:View,savedInstanceState:Bundle?
{
super.onViewCreatedview,savedInstanceState
//...
imagePath=FilerequireContext.filesDir,图像
newFile=FileimagePath,默认值为_image.jpg
uri=getUriForFile
要求文本,
requireContext.applicationContext.packageName,
新文件
binding.butMakeNewImage.setOnClickListener{
takePicture.launchuri
}
}
private val takePicture=registerForActivityResultActivityResultContracts.takePicture{isSaved->
如果被保存
{
binding.imgSelected.setImageURIuri
}
}
}
如果有帮助,这是完整的错误日志
2021-01-16 16:15:38.871 9433-9433/com.myniprojects.pixagram W/ImageView: Unable to open content: content://com.myniprojects.pixagram/my_images/default_image.jpg
java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
at androidx.core.content.FileProvider.openFile(FileProvider.java:566)
at android.content.ContentProvider.openAssetFile(ContentProvider.java:1740)
at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1922)
at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1989)
at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:539)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1698)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1514)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1198)
at android.graphics.ImageDecoder$ContentResolverSource.createImageDecoder(ImageDecoder.java:282)
at android.graphics.ImageDecoder.decodeDrawableImpl(ImageDecoder.java:1743)
at android.graphics.ImageDecoder.decodeDrawable(ImageDecoder.java:1736)
at android.widget.ImageView.getDrawableFromUri(ImageView.java:1023)
at android.widget.ImageView.resolveUri(ImageView.java:992)
at android.widget.ImageView.setImageURI(ImageView.java:561)
at androidx.appcompat.widget.AppCompatImageView.setImageURI(AppCompatImageView.java:120)
at com.myniprojects.pixagram.ui.fragments.AddFragment$takePicture$1.onActivityResult(AddFragment.kt:105)
at com.myniprojects.pixagram.ui.fragments.AddFragment$takePicture$1.onActivityResult(AddFragment.kt:30)
at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:361)
at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:321)
at androidx.activity.ComponentActivity.onActivityResult(ComponentActivity.java:631)
at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:164)
at android.app.Activity.dispatchActivityResult(Activity.java:8412)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5580)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5628)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2473)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8347)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
2021-01-16 16:15:38.871 9433-9433/com.myniprojects.pixagram W/ImageView: resolveUri failed on bad bitmap uri: content://com.myniprojects.pixagram/my_images/default_image.jpg
在英语中,我们可以阅读
ActivityResultContract,用于拍摄照片并将其保存到提供的内容Uri中。
如果图像保存到给定的Uri中,则返回true
那么,为什么我在尝试使用Uri中的此图像时出现错误?我终于找到了解决方法。我不确定,但我认为问题中的File/Uri有问题。下面是一个如何捕获图像的分步解决方案 依赖项: 显示: 检查是否授予Manifest.permission.CAMERA。如果没有,请请求许可 在片段中创建ActivityResultLauncher,如下所示: 要启动takePicture,例如在按钮上单击 小费。如果API级别低于21时收到消息“权限拒绝”,请尝试执行以下操作: val ResultLancher=registerForActivityResult 对象:ActivityResultContracts.TakePicture { 覆盖有趣的createIntent 上下文:上下文, 输入:Uri :意图 { val intent=super.createIntentcontext,输入 如果Build.VERSION.SDK\u INT 如果成功 { //待办事项 } } resultLauncher.launchphotoUri
我终于找到了解决方法。我不确定,但我认为问题是File/Uri有问题。下面是一个如何捕获图像的分步解决方案 依赖项: 显示: 检查Manifest.permission.CAMERA是否已授予。如果未授予,请请求权限 在片段中创建ActivityResultLauncher,如下所示: 要启动takePicture,例如在按钮上单击 提示:如果API级别低于21,则尝试执行以下操作: val ResultLancher=registerForActivityResult 对象:ActivityResultContracts.TakePicture { 覆盖有趣的createIntent 上下文:上下文, 输入:Uri :意图 { val intent=super.createIntentcontext,输入 如果Build.VERSION.SDK\u INT 如果成功 { //待办事项 } } resultLauncher.launchphotoUri
从代码的快速扫描来看,我的猜测是,true真的意味着我们从摄像头应用程序中得到了结果。摄像头应用程序有缺陷,特别是对于动作图像捕获。因此,尽管有文档,我不会假设图像最终被写在你期望的地方。因为它是你自己的文件,你可以在使用它之前检查文件是否存在。我会检查文件是否存在,并按如下方式记录:存在:${newFile.exists}。它打印存在:false。这意味着我做错了什么?我在手机上测试过,但现在在模拟器上,相同的代码返回false作为isSavedSo,这意味着我做错了什么?-可能不是,尽管我还没有玩太多ActivityResults,因为它仍然是预发布的。我猜你有一个有缺陷的摄像头PP,一个无法应付ActoNoIGIMAGE捕获,或者至少不能应付内容:// Uri值很好。如果你的测试设备运行Android 10或更老,你可能会考虑安装另一个相机应用程序,例如,打开相机,看看你的应用程序的行为与它。我这样做,就像你说的,在打开的相机,我没有保存图像。所以我开始CH。用FileProvider更改所有这些内容,现在似乎可以工作了。ThanksI参加聚会可能有点晚了,但是你的imagePath imagePath=FileRequireText.FileDir,图像存在吗?我认为android不会在不存在文件的情况下自动创建文件的父目录。快速扫描代码,我猜这是真的,意味着我们要继续相机应用程序的结果不正常。相机应用程序有缺陷,特别是对于动作图像捕获。因此,尽管有文档,我不会假设图像最终会被写入您期望的位置。因为是您
在使用自己的文件之前,您可以检查该文件是否存在。我检查该文件是否存在,并按如下方式记录:exists:${newFile.exists}。它存在:假。这意味着我做错了什么?我曾在手机上测试过这个,但现在在模拟器上,相同的代码返回false作为isSavedSo,这意味着我做错了什么可能不会,虽然我还没有玩太多的ActivityResults,因为它仍然是AFAIK的预发行版。我的猜测是,你有一个有缺陷的摄像头应用程序,它不能很好地处理动作、图像、或者至少不能很好地处理content://Uri值。如果你的测试设备运行Android 10或更高版本,你可能会考虑安装另一个摄像头应用程序,比如打开摄像头,看看你的应用程序是如何运行的。我像你说的那样做,在打开的摄像头中,我保存图像失败了。所以我开始用FileProvider来改变所有这些东西,现在它似乎起作用了。ThanksI参加聚会可能有点晚,但是您的imagePath imagePath=FilerequireContext.filesDir,图像是否存在?我认为,如果文件不存在,android不会自动创建其父目录。
2021-01-16 16:15:38.871 9433-9433/com.myniprojects.pixagram W/ImageView: Unable to open content: content://com.myniprojects.pixagram/my_images/default_image.jpg
java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
at androidx.core.content.FileProvider.openFile(FileProvider.java:566)
at android.content.ContentProvider.openAssetFile(ContentProvider.java:1740)
at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1922)
at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1989)
at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:539)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1698)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1514)
at android.content.ContentResolver.openInputStream(ContentResolver.java:1198)
at android.graphics.ImageDecoder$ContentResolverSource.createImageDecoder(ImageDecoder.java:282)
at android.graphics.ImageDecoder.decodeDrawableImpl(ImageDecoder.java:1743)
at android.graphics.ImageDecoder.decodeDrawable(ImageDecoder.java:1736)
at android.widget.ImageView.getDrawableFromUri(ImageView.java:1023)
at android.widget.ImageView.resolveUri(ImageView.java:992)
at android.widget.ImageView.setImageURI(ImageView.java:561)
at androidx.appcompat.widget.AppCompatImageView.setImageURI(AppCompatImageView.java:120)
at com.myniprojects.pixagram.ui.fragments.AddFragment$takePicture$1.onActivityResult(AddFragment.kt:105)
at com.myniprojects.pixagram.ui.fragments.AddFragment$takePicture$1.onActivityResult(AddFragment.kt:30)
at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:361)
at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:321)
at androidx.activity.ComponentActivity.onActivityResult(ComponentActivity.java:631)
at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:164)
at android.app.Activity.dispatchActivityResult(Activity.java:8412)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5580)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5628)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2473)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8347)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
2021-01-16 16:15:38.871 9433-9433/com.myniprojects.pixagram W/ImageView: resolveUri failed on bad bitmap uri: content://com.myniprojects.pixagram/my_images/default_image.jpg
implementation "androidx.activity:activity-ktx:1.2.0-rc01"
implementation "androidx.fragment:fragment-ktx:1.3.0-rc01"
implementation "com.github.bumptech.glide:glide:4.11.0"
<uses-permission android:name="android.permission.CAMERA" />
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
</application>
<paths>
<external-path name="my_images"
path="Android/data/com.example.name/files/Pictures" />
</paths
private lateinit var uri: Uri
private val takePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSaved ->
if (isSaved)
{
glide
.load(uri)
.into(binding.imgSelected)
}
}
binding.butMakeNewImage.setOnClickListener {
val photoFile = File.createTempFile(
"IMG_",
".jpg",
requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
)
uri = FileProvider.getUriForFile(
requireContext(),
"${requireContext().packageName}.provider",
photoFile
)
takePicture.launch(uri)
}