首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin: java.lang.IllegalArgumentException:找不到授权xxx的提供者的元数据

Kotlin: java.lang.IllegalArgumentException:找不到授权xxx的提供者的元数据
EN

Stack Overflow用户
提问于 2022-06-16 20:10:38
回答 1查看 337关注 0票数 0

我的应用程序包括经典的“分享这个应用程序”菜单选项,它需要两个屏幕截图,并通过邮件发送,以及一个促销文本。

在从Java迁移到Kotlin之前,它运行良好,但现在在Kotlin,它开始抛出一个异常。

奇怪的是,即使是异常(在logcat中也可以看到)--进程运行良好,应用程序没有崩溃(至少不是以可见的方式)--并且共享过程已经完成,例如,如果您选择电子邮件,电子邮件将与图像一起接收。

Manifest.xml

代码语言:javascript
复制
<provider
    android:name=".helpers.GenericFileProvider"
    android:authorities="${applicationId}.GenericFileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

GenericFileProvider:

代码语言:javascript
复制
package com.xxx.xxx.helpers

import androidx.core.content.FileProvider

class GenericFileProvider : FileProvider()

provider_paths.xml:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path name="cache" path="."/>
</paths>

shareFile:

代码语言:javascript
复制
@JvmStatic
fun shareFile(uris: ArrayList<Uri?>?, fileType: String?) {
    try {
        val share = Intent(Intent.ACTION_SEND_MULTIPLE)
        share.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        share.type = fileType
        val strSubject = getStringResourceByName("mainmenu_sharethisapp_subject")
        share.putExtra(Intent.EXTRA_SUBJECT, strSubject)
        share.putParcelableArrayListExtra(Intent.EXTRA_TEXT, uris)
        share.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
        activity!!.get()!!.startActivity(
            Intent.createChooser(
                share,
                getStringResourceByName("mainmenu_sharethisapp_sharethoughttitle")
            )
        )
    } catch (ex: Exception) {
        Toast.makeText(activity!!.get(), ex.message.toString(), Toast.LENGTH_LONG).show()
    }
}

onImageProcessingFinished:

代码语言:javascript
复制
fun onImageProcessingFinished(ipr: ImageProcessingResult, activity: Activity) {
    val uris = ArrayList<Uri?>()
    for (file in ipr.screenShotFiles) {
        val uri = FileProvider.getUriForFile(activity,  activity.packageName + ".GenericFileProvider", file)
        if (uri!=null) uris.add(uri)
    }
    AWDrawerMenu.listener = activity as IActionListeners
    AWDrawerMenu.activity = WeakReference(activity)
    AWDrawerMenu.shareFile(uris, "image/jpg")
}

例外:

代码语言:javascript
复制
2022-06-16 22:01:08.427 11357-11378/com.xxx.xxx E/DatabaseUtils: Writing exception to parcel
    java.lang.SecurityException: Permission Denial: reading com.xxx.xxx.helpers.GenericFileProvider uri content://com.xxx.xxx.GenericFileProvider/cache/xxx.jpg from pid=6474, uid=1000 requires the provider be exported, or grantUriPermission()
        at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:820)
        at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:684)
        at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:674)
        at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:548)
        at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:327)
        at android.os.Binder.execTransactInternal(Binder.java:1154)
        at android.os.Binder.execTransact(Binder.java:1123)

编辑1:

如果我将onImageProcessingFinished方法替换为下一个

代码语言:javascript
复制
fun onImageProcessingFinished(ipr: ImageProcessingResult, activity: Activity) {
    val uris = ArrayList<Uri?>()
    for (file in ipr.screenShotFiles) {
        val uri = FileProvider.getUriForFile(activity,  activity.packageName + ".helpers.GenericFileProvider", file)
        if (uri!=null) uris.add(uri)
    }
    AWDrawerMenu.listener = activity as IActionListeners
    AWDrawerMenu.activity = WeakReference(activity)
    AWDrawerMenu.shareFile(uris, "image/jpg")
}

在.helpers之前添加GenericFileProvider (最终是GenericFileProvider的完整包名),然后抛出以下异常(在本例中,应用程序会崩溃):

代码语言:javascript
复制
2022-06-16 21:48:10.203 10694-10694/com.xxx.xxx E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.xxx.xxx, PID: 10694
    java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority com.xxx.xxx.helpers.GenericFileProvider
        at androidx.core.content.FileProvider.parsePathStrategy(FileProvider.java:662)
        at androidx.core.content.FileProvider.getPathStrategy(FileProvider.java:635)
        at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:441)
        at com.xxx.xxx.component.drawer.AWDrawer$Companion.onImageProcessingFinished(AWDrawer.kt:294)
        at com.xxx.xxx.activities.main.MainActivity.onImageProcessingFinished(MainActivity.kt:448)
        at com.xxx.xxx.activities.main.MainActivity.onShareThisApp$lambda-6(MainActivity.kt:443)
        at com.xxx.xxx.activities.main.MainActivity.$r8$lambda$c-xNLWLGog-3ah1DvHN4y6HCHsw(Unknown Source:0)
        at com.xxx.xxx.activities.main.MainActivity$$ExternalSyntheticLambda3.onComplete(Unknown Source:4)
        at com.xxx.xxx.helpers.TaskRunner.executeAsync$lambda-1$lambda-0(TaskRunner.kt:24)
        at com.xxx.xxx.helpers.TaskRunner.$r8$lambda$ItjAcdIefpXj05LbTtje15JKSPM(Unknown Source:0)
        at com.xxx.xxx.helpers.TaskRunner$$ExternalSyntheticLambda0.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-17 18:12:21

最后,我发现我遇到的问题和这里描述的完全一样:

Permission Denial while sharing file with FileProvider

幸运的是,同样的解决方案也适用于我。

我不得不更换这个:

代码语言:javascript
复制
@JvmStatic
fun shareFile(uris: ArrayList<Uri?>?, fileType: String?) {
    try {
        val share = Intent(Intent.ACTION_SEND_MULTIPLE)
        share.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        share.type = fileType
        val strSubject = getStringResourceByName("mainmenu_sharethisapp_subject")
        share.putExtra(Intent.EXTRA_SUBJECT, strSubject)
        share.putParcelableArrayListExtra(Intent.EXTRA_TEXT, uris)
        share.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
        activity!!.get()!!.startActivity(
            Intent.createChooser(
                share,
                getStringResourceByName("mainmenu_sharethisapp_sharethoughttitle")
            )
        )
        activity!!.get()!!.startActivity(share)
    } catch (ex: Exception) {
        Toast.makeText(activity!!.get(), ex.message.toString(), Toast.LENGTH_LONG).show()
    }
}

通过这一点:

代码语言:javascript
复制
@JvmStatic
fun shareFile(uris: ArrayList<Uri?>?, fileType: String?) {
    try {
        val share = Intent(Intent.ACTION_SEND_MULTIPLE)
        share.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        share.type = fileType
        val strSubject = getStringResourceByName("mainmenu_sharethisapp_subject")
        share.putExtra(Intent.EXTRA_SUBJECT, strSubject)
        share.putParcelableArrayListExtra(Intent.EXTRA_TEXT, uris)
        share.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
        /*activity!!.get()!!.startActivity(
            Intent.createChooser(
                share,
                getStringResourceByName("mainmenu_sharethisapp_sharethoughttitle")
            )
        )*/
        activity!!.get()!!.startActivity(share)
    } catch (ex: Exception) {
        Toast.makeText(activity!!.get(), ex.message.toString(), Toast.LENGTH_LONG).show()
    }
}

选择器看起来有点不同(不知道为什么),但它很有效。

编辑1:

好的,最后的工作代码:

代码语言:javascript
复制
@JvmStatic
fun shareFile(uris: ArrayList<Uri?>?, fileType: String?) {
    try {
        val strSubject = getStringResourceByName("mainmenu_sharethisapp_subject")
        val strMessage = getStringResourceByName("mainmenu_sharethisapp_message")
        val intent = Intent()
        intent.type = fileType
        intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        intent.putExtra(Intent.EXTRA_SUBJECT, strSubject)
        intent.putExtra(Intent.EXTRA_TEXT, strMessage)

        if (uris!!.size == 0) {
            return
        } else if (uris.size == 1) {
            val uri = uris[0]!!
            intent.action = Intent.ACTION_SEND
            intent.putExtra(Intent.EXTRA_STREAM, uri)
            intent.clipData = ClipData.newRawUri("", uri)
        } else {
            intent.action = Intent.ACTION_SEND_MULTIPLE
            intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
            val clipData = ClipData.newRawUri("", uris[0])
            for (i in 1 until uris.size) {
                val uri = uris[i]!!
                clipData.addItem(ClipData.Item(uri))
            }
            intent.clipData = clipData
        }

        activity!!.get()!!.startActivity(
            Intent.createChooser(
                intent, getStringResourceByName("mainmenu_sharethisapp_sharethoughttitle")
            )
        )
    } catch (ex: Exception) {
        Toast.makeText(activity!!.get(), ex.message.toString(), Toast.LENGTH_LONG).show()
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72651390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档