我想使用我的默认 PDF 应用程序打开一个
GmsDocumentScanningResult.Pdf
对象。
我尝试过以下方法:
resultIntent?.pdf?.let { pdf: GmsDocumentScanningResult.Pdf ->
val pdfUri = pdf.uri
val file = pdfUri.toFile()
if (file.exists()) {
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(file.toUri(), "application/pdf")
try {
startActivity(intent)
} catch (e: FileUriExposedException) {
}
}
}
但它抛出 FileUriExposedException 并显示以下消息:
file:///data/user/0/com.mypackage.docscanner/cache/mlkit_docscan_ui_client/9724995915195.pdf exposed beyond app through Intent.getData()
我想我需要使用
android.support.v4.content.FileProvider
,就像在这个问题中一样,但我不确定如何在这里实现。
我也尝试过这个:
AndroidManifest.xml
<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/provider_paths" />
</provider>
</application>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path
name="cache"
path="." />
</paths>
val pdfFile = FileProvider.getUriForFile(baseContext, applicationContext.packageName + ".provider", resultIntent?.pdf?.uri?.toFile() ?: File("")).toFile()
if (pdfFile.exists()) {
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(pdfFile.toUri(), "application/pdf")
try {
startActivity(intent)
} catch (e: Exception) {
//
}
}
}
但它也崩溃了,这次例外:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=95110657, result=-1, data=Intent { (has extras) }} to activity {com.hikarisource.docscanner/com.hikarisource.docscanner.MainActivity}: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.hikarisource.docscanner/cache/mlkit_docscan_ui_client/1376275955600.pdf
at android.app.ActivityThread.deliverResults(ActivityThread.java:5323)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5362)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:67)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Caused by: java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/com.hikarisource.docscanner/cache/mlkit_docscan_ui_client/1376275955600.pdf
at androidx.core.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:849)
at androidx.core.content.FileProvider.getUriForFile(FileProvider.java:452)
at com.hikarisource.docscanner.MainActivity.registerScanner$lambda$2(MainActivity.kt:57)
at com.hikarisource.docscanner.MainActivity.$r8$lambda$7_JDnBxGZf3SKr0da9a7J8NBWkY(Unknown Source:0)
at com.hikarisource.docscanner.MainActivity$$ExternalSyntheticLambda0.onActivityResult(Unknown Source:4)
at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:414)
at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:371)
at androidx.activity.ComponentActivity.onActivityResult(ComponentActivity.java:845)
at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:8628)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5316)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5362)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:67)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
只是在如何设置意图上有一点不同:
AndroidManifest.xml
<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/provider_paths" />
</provider>
</application>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
<cache-path
name="mlkit_docscan_ui_client"
path="." />
</paths>
resultIntent?.pdf?.let { pdf: GmsDocumentScanningResult.Pdf ->
val pdfUri = it.uri
val pdfFileUri = FileProvider.getUriForFile(activity, activity.packageName + ".provider", pdfUri.toFile())
val browserIntent = Intent(Intent.ACTION_VIEW, pdfFileUri)
browserIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
activity.startActivity(browserIntent)
}