启动 ChooserActivity 以与其他应用共享图像后应用关闭
App closed after starting ChooserActivity to share image with other apps
在带有 Android10 的三星设备上,我们遇到了问题,我们的应用程序在启动 ChooserActivity 以共享我们的应用程序创建的图像后关闭。
日志或其他任何内容都没有异常。对于用户来说,我们的应用程序似乎刚刚关闭。
我们在其他设备上没有看到这种行为。
但是在我的 Android 10 诺基亚测试设备上 logcat.
中有一个条目
2020-05-06 15:48:04.033 4509-4543/packagename E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://packagename.provider/cache/image-to-share.jpeg from pid=2753, uid=1000 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:742)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:615)
at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:606)
at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:520)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:307)
at android.os.Binder.execTransactInternal(Binder.java:1021)
at android.os.Binder.execTransact(Binder.java:994)
随后出现警告
2020-05-06 15:48:04.034 2753-5090/? W/ChooserActivity: Could not load (content://packagename.provider/cache/image-to-share.jpeg) thumbnail/name for preview. If desired, consider using Intent#createChooser to launch the ChooserActivity, and set your Intent's clipData and flags in accordance with that method's documentation
我不知道这是否是三星设备不适合我们应用程序的原因。在我们的测试设备上,即使日志中出现此消息,也一切正常。
这是我们如何启动 ChooserActivity 的代码
val share = Intent(Intent.ACTION_SEND)
share.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
share.type = "*/*"
share.putExtra(Intent.EXTRA_TEXT, link)
share.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(activity!!, BuildConfig.APPLICATION_ID + ".provider", fileToShare!!))
startActivityForResult(Intent.createChooser(share, "Share Image"), REQUEST_CODE_CHOOSER_INTENT)
这里是我们文件提供者在AndroidManifest.xml
中的定义
<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>
file_paths.xml
看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="cache" path="."/>
</paths>
是否有人在三星设备上也遇到了这个问题,或者可以告诉我如何解决我们在日志中看到的错误,以便我们测试是否可以解决三星设备上的问题?
更新:
我们在日志中发现了以下异常。
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: android:ui, PID: 26528
java.lang.RuntimeException: java.net.URISyntaxException: Illegal character in authority at index 8: https://{{ogunsecureurl}}/
at com.android.okhttp.HttpUrl.uri(HttpUrl.java:357)
at com.android.okhttp.internal.http.RouteSelector.resetNextProxy(RouteSelector.java:123)
at com.android.okhttp.internal.http.RouteSelector.<init>(RouteSelector.java:63)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:188)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:144)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:106)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:400)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:333)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at com.android.internal.app.ChooserActivity.semCreateWebThumbnail(ChooserActivity.java:3194)
at com.android.internal.app.ChooserActivity.semLoadWebMetaData(ChooserActivity.java:3151)
at com.android.internal.app.ChooserActivity$ContentPreviewCoordinator.lambda$semLoadUrlIntoView$ChooserActivity$ContentPreviewCoordinator(ChooserActivity.java:593)
at com.android.internal.app.-$$Lambda$ChooserActivity$ContentPreviewCoordinatorJseasSRHRaydwh9UhAQ6FjbwOA.run(Unknown Source:12)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.net.URISyntaxException: Illegal character in authority at index 8: https://{{ogunsecureurl}}/
at java.net.URI$Parser.fail(URI.java:2892)
at java.net.URI$Parser.parseAuthority(URI.java:3230)
at java.net.URI$Parser.parseHierarchical(URI.java:3141)
at java.net.URI$Parser.parse(URI.java:3097)
at java.net.URI.<init>(URI.java:583)
at com.android.okhttp.HttpUrl.uri(HttpUrl.java:350)
at com.android.okhttp.internal.http.RouteSelector.resetNextProxy(RouteSelector.java:123)
at com.android.okhttp.internal.http.RouteSelector.<init>(RouteSelector.java:63)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:188)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:144)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:106)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:400)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:333)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at com.android.internal.app.ChooserActivity.semCreateWebThumbnail(ChooserActivity.java:3194)
at com.android.internal.app.ChooserActivity.semLoadWebMetaData(ChooserActivity.java:3151)
at com.android.internal.app.ChooserActivity$ContentPreviewCoordinator.lambda$semLoadUrlIntoView$ChooserActivity$ContentPreviewCoordinator(ChooserActivity.java:593)
at com.android.internal.app.-$$Lambda$ChooserActivity$ContentPreviewCoordinatorJseasSRHRaydwh9UhAQ6FjbwOA.run(Unknown Source:12)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
有没有人知道这里发生了什么。 uri 权限集基本上就是我们的应用程序包名称。
如错误中所述,使文件提供程序可导出,在 AndroidManifest.xml 文件的提供程序组件中 -
android:exported="true"
试试吧。所以你的提供者看起来像 -
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="true"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
我设法通过一些变通办法解决了这个问题。当我试图将额外的 URL 传递给 ChooserActivity 时发生错误,例如
share.putExtra(Intent.EXTRA_TEXT, "https://my.domain.com")
这会导致 java.net.URISyntaxException
仅在带有 Android 10 的三星设备上出现,我在上面的问题中提到过。
像这样传递 URL 是可行的。
share.putExtra(Intent.EXTRA_TEXT, "https://www.my.domain.com")
但是我需要一个没有 www 的 URL,所以我在 URL 前后放了一个 space。这也有效。可能是因为 Samsung ChooserActivity 没有尝试将此字符串解析为 URL.
share.putExtra(Intent.EXTRA_TEXT, " https://my.domain.com ")
这个技巧对我有用。也许有人觉得它也有用,或者对我有解释,为什么会这样。
在带有 Android10 的三星设备上,我们遇到了问题,我们的应用程序在启动 ChooserActivity 以共享我们的应用程序创建的图像后关闭。
日志或其他任何内容都没有异常。对于用户来说,我们的应用程序似乎刚刚关闭。
我们在其他设备上没有看到这种行为。
但是在我的 Android 10 诺基亚测试设备上 logcat.
中有一个条目2020-05-06 15:48:04.033 4509-4543/packagename E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: Permission Denial: reading androidx.core.content.FileProvider uri content://packagename.provider/cache/image-to-share.jpeg from pid=2753, uid=1000 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:742)
at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:615)
at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:606)
at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:520)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:307)
at android.os.Binder.execTransactInternal(Binder.java:1021)
at android.os.Binder.execTransact(Binder.java:994)
随后出现警告
2020-05-06 15:48:04.034 2753-5090/? W/ChooserActivity: Could not load (content://packagename.provider/cache/image-to-share.jpeg) thumbnail/name for preview. If desired, consider using Intent#createChooser to launch the ChooserActivity, and set your Intent's clipData and flags in accordance with that method's documentation
我不知道这是否是三星设备不适合我们应用程序的原因。在我们的测试设备上,即使日志中出现此消息,也一切正常。
这是我们如何启动 ChooserActivity 的代码
val share = Intent(Intent.ACTION_SEND)
share.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
share.type = "*/*"
share.putExtra(Intent.EXTRA_TEXT, link)
share.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(activity!!, BuildConfig.APPLICATION_ID + ".provider", fileToShare!!))
startActivityForResult(Intent.createChooser(share, "Share Image"), REQUEST_CODE_CHOOSER_INTENT)
这里是我们文件提供者在AndroidManifest.xml
<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>
file_paths.xml
看起来像这样
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="cache" path="."/>
</paths>
是否有人在三星设备上也遇到了这个问题,或者可以告诉我如何解决我们在日志中看到的错误,以便我们测试是否可以解决三星设备上的问题?
更新: 我们在日志中发现了以下异常。
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: android:ui, PID: 26528
java.lang.RuntimeException: java.net.URISyntaxException: Illegal character in authority at index 8: https://{{ogunsecureurl}}/
at com.android.okhttp.HttpUrl.uri(HttpUrl.java:357)
at com.android.okhttp.internal.http.RouteSelector.resetNextProxy(RouteSelector.java:123)
at com.android.okhttp.internal.http.RouteSelector.<init>(RouteSelector.java:63)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:188)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:144)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:106)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:400)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:333)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at com.android.internal.app.ChooserActivity.semCreateWebThumbnail(ChooserActivity.java:3194)
at com.android.internal.app.ChooserActivity.semLoadWebMetaData(ChooserActivity.java:3151)
at com.android.internal.app.ChooserActivity$ContentPreviewCoordinator.lambda$semLoadUrlIntoView$ChooserActivity$ContentPreviewCoordinator(ChooserActivity.java:593)
at com.android.internal.app.-$$Lambda$ChooserActivity$ContentPreviewCoordinatorJseasSRHRaydwh9UhAQ6FjbwOA.run(Unknown Source:12)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
Caused by: java.net.URISyntaxException: Illegal character in authority at index 8: https://{{ogunsecureurl}}/
at java.net.URI$Parser.fail(URI.java:2892)
at java.net.URI$Parser.parseAuthority(URI.java:3230)
at java.net.URI$Parser.parseHierarchical(URI.java:3141)
at java.net.URI$Parser.parse(URI.java:3097)
at java.net.URI.<init>(URI.java:583)
at com.android.okhttp.HttpUrl.uri(HttpUrl.java:350)
at com.android.okhttp.internal.http.RouteSelector.resetNextProxy(RouteSelector.java:123)
at com.android.okhttp.internal.http.RouteSelector.<init>(RouteSelector.java:63)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:188)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:144)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:106)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:400)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:333)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at com.android.internal.app.ChooserActivity.semCreateWebThumbnail(ChooserActivity.java:3194)
at com.android.internal.app.ChooserActivity.semLoadWebMetaData(ChooserActivity.java:3151)
at com.android.internal.app.ChooserActivity$ContentPreviewCoordinator.lambda$semLoadUrlIntoView$ChooserActivity$ContentPreviewCoordinator(ChooserActivity.java:593)
at com.android.internal.app.-$$Lambda$ChooserActivity$ContentPreviewCoordinatorJseasSRHRaydwh9UhAQ6FjbwOA.run(Unknown Source:12)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
有没有人知道这里发生了什么。 uri 权限集基本上就是我们的应用程序包名称。
如错误中所述,使文件提供程序可导出,在 AndroidManifest.xml 文件的提供程序组件中 -
android:exported="true"
试试吧。所以你的提供者看起来像 -
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="true"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
我设法通过一些变通办法解决了这个问题。当我试图将额外的 URL 传递给 ChooserActivity 时发生错误,例如
share.putExtra(Intent.EXTRA_TEXT, "https://my.domain.com")
这会导致 java.net.URISyntaxException
仅在带有 Android 10 的三星设备上出现,我在上面的问题中提到过。
像这样传递 URL 是可行的。
share.putExtra(Intent.EXTRA_TEXT, "https://www.my.domain.com")
但是我需要一个没有 www 的 URL,所以我在 URL 前后放了一个 space。这也有效。可能是因为 Samsung ChooserActivity 没有尝试将此字符串解析为 URL.
share.putExtra(Intent.EXTRA_TEXT, " https://my.domain.com ")
这个技巧对我有用。也许有人觉得它也有用,或者对我有解释,为什么会这样。