快捷方式不启动 Android 中的文件 Q
Shortcut Doesn't Launch The File In Android Q
编辑:
当我点击固定的快捷方式时,我在 system_process
中的日志如下:
2019-10-26 20:00:16.086 2047-3533/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.VIEW dat=file:///storage/emulated/0/Download/AAD.pdf typ=application/pdf flg=0x10000000 cmp=com.google.android.apps.docs/com.google.android.apps.viewer.PdfViewerActivity bnds=[439,84][641,337]} from uid 10147
2019-10-26 20:00:16.100 2047-2047/system_process W/ActivityManager: Unable to start service Intent { act=android.service.appprediction.AppPredictionService cmp=com.google.android.as/com.google.android.apps.miphone.aiai.app.AiAiPredictionService } U=0: not found
2019-10-26 20:00:16.100 2047-2047/system_process W/RemoteAppPredictionService: could not bind to Intent { act=android.service.appprediction.AppPredictionService cmp=com.google.android.as/com.google.android.apps.miphone.aiai.app.AiAiPredictionService } using flags 67108865
简而言之,固定快捷方式在 Android 10 中无法打开,但在旧版本中可以使用。在 Android 10 中,当我单击快捷方式时,Drive PDF Viewer 打开,但实际文件显示为黑色 space 并在一秒钟内关闭该应用程序。
旧:
我的 Android 应用程序目标 API 级别 28。它将 PDF 文件的快捷方式固定到主屏幕,点击该图标显然可以打开文件。直到 Android Pie,它工作得很好。但是当我在 API 29 上测试它时,单击该图标会打开 PDF 查看器并强制关闭而不会出现错误。这是相关代码。
private fun addShortcutInOreo(path1: String, pdfName: String) {
val file = File(path1)
try {
Log.d("Data", file.path)
val pdfIntent = Intent(Intent.ACTION_VIEW)
val uri = Uri.fromFile(file)
pdfIntent.setDataAndType(uri, "application/pdf")
pdfIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
pdfIntent.flags = Intent.FLAG_GRANT_WRITE_URI_PERMISSION
Log.d("DataPath", uri.path)
Log.d("DataPath", pdfName)
if (Build.VERSION.SDK_INT > 25) {
val shortcutManager = getSystemService(ShortcutManager::class.java)
// Check which icon is to be pinned
image = if (blueIcon.isChecked)
R.drawable.pdf
else
R.drawable.pdf2
// Create a shortcut
val shortcut = ShortcutInfo.Builder(this, pdfName)
.setShortLabel(pdfName)
.setLongLabel(pdfName)
.setIcon(Icon.createWithResource(this, image))
.setIntent(pdfIntent)
.build()
shortcutManager.requestPinShortcut(shortcut, null)
}
} catch (e: Exception) {
errorMessage(e)
}
}
记录的数据在这里。第一行显示文件路径。第二行显示 Uri。第三行只是给出了提取的文件名。我这样做只是为了检查我的代码是否一切正常。
2019-08-02 13:43:14.160 3306-3306/com.parassidhu.pdfpin D/Data: /storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:43:14.160 3306-3306/com.parassidhu.pdfpin D/DataPath: file:///storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:43:14.160 3306-3306/com.parassidhu.pdfpin D/DataPath: Nakal
API28 的日志相同:
2019-08-02 13:55:07.853 5341-5341/com.parassidhu.pdfpin D/Data: /storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:55:07.853 5341-5341/com.parassidhu.pdfpin D/DataPath: file:///storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:55:07.853 5341-5341/com.parassidhu.pdfpin D/DataPath: Nakal
由于没有错误,我正在摸不着头脑,因为可能出了什么问题。我在 Android Q 中阅读了有关 Scoped Storage 的内容,但这不适用于此处,因为我不是针对 Q。我在 Android Q 中阅读了其他行为更改,但 none 确实适用据我所知。
可能是什么问题?感谢阅读!
Uri.fromFile()
自 Android 7.0 以来已被有效禁止,因为它会触发 FileUriExposedException
.
在您的应用中使用 FileProvider
并 FileProvider.getUriForFile()
创建 Uri
以在您的 Intent
中使用。
感谢@CommonsWare的指点,我解决了这个问题。我做了两个更改:
对于 Android 7.0 及更高版本,我使用 FileProvider.getUriForFile()
而不是 @CommonsWare 建议的 Uri.fromFile()
。
而不是使用setFlags()
(在Kotlin的语法中,它是intent.flags = <flag>
),我使用addFlags()
并传递Intent.FLAG_GRANT_READ_URI_PERMISSION
。
解释:
第一个更改确实是必要的,因为使用 Uri.fromFile()
方法导致 FileUriExposedException
for Android 7.0+。不在应用程序中,因为单击快捷方式时,启动 activity 不属于我的应用程序。这就是为什么我抓不到它的原因。
我猜这个变化是罪魁祸首。如果我们不添加给定的标志,则 PDF 打开 activity(或应用程序)没有读取文件内容(或 uri)的权限。这就是 activity 打开一秒钟然后关闭的原因,因为它无法读取文件。
关于 setFlags()
与 addFlags()
,因为 setFlags()
删除了现有的标志并添加了指定的标志,所以它不起作用。但是 addFlags()
保留现有的标志并添加指定的标志。因此 addFlags()
有效。
编辑:
当我点击固定的快捷方式时,我在 system_process
中的日志如下:
2019-10-26 20:00:16.086 2047-3533/system_process I/ActivityTaskManager: START u0 {act=android.intent.action.VIEW dat=file:///storage/emulated/0/Download/AAD.pdf typ=application/pdf flg=0x10000000 cmp=com.google.android.apps.docs/com.google.android.apps.viewer.PdfViewerActivity bnds=[439,84][641,337]} from uid 10147
2019-10-26 20:00:16.100 2047-2047/system_process W/ActivityManager: Unable to start service Intent { act=android.service.appprediction.AppPredictionService cmp=com.google.android.as/com.google.android.apps.miphone.aiai.app.AiAiPredictionService } U=0: not found
2019-10-26 20:00:16.100 2047-2047/system_process W/RemoteAppPredictionService: could not bind to Intent { act=android.service.appprediction.AppPredictionService cmp=com.google.android.as/com.google.android.apps.miphone.aiai.app.AiAiPredictionService } using flags 67108865
简而言之,固定快捷方式在 Android 10 中无法打开,但在旧版本中可以使用。在 Android 10 中,当我单击快捷方式时,Drive PDF Viewer 打开,但实际文件显示为黑色 space 并在一秒钟内关闭该应用程序。
旧:
我的 Android 应用程序目标 API 级别 28。它将 PDF 文件的快捷方式固定到主屏幕,点击该图标显然可以打开文件。直到 Android Pie,它工作得很好。但是当我在 API 29 上测试它时,单击该图标会打开 PDF 查看器并强制关闭而不会出现错误。这是相关代码。
private fun addShortcutInOreo(path1: String, pdfName: String) {
val file = File(path1)
try {
Log.d("Data", file.path)
val pdfIntent = Intent(Intent.ACTION_VIEW)
val uri = Uri.fromFile(file)
pdfIntent.setDataAndType(uri, "application/pdf")
pdfIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
pdfIntent.flags = Intent.FLAG_GRANT_WRITE_URI_PERMISSION
Log.d("DataPath", uri.path)
Log.d("DataPath", pdfName)
if (Build.VERSION.SDK_INT > 25) {
val shortcutManager = getSystemService(ShortcutManager::class.java)
// Check which icon is to be pinned
image = if (blueIcon.isChecked)
R.drawable.pdf
else
R.drawable.pdf2
// Create a shortcut
val shortcut = ShortcutInfo.Builder(this, pdfName)
.setShortLabel(pdfName)
.setLongLabel(pdfName)
.setIcon(Icon.createWithResource(this, image))
.setIntent(pdfIntent)
.build()
shortcutManager.requestPinShortcut(shortcut, null)
}
} catch (e: Exception) {
errorMessage(e)
}
}
记录的数据在这里。第一行显示文件路径。第二行显示 Uri。第三行只是给出了提取的文件名。我这样做只是为了检查我的代码是否一切正常。
2019-08-02 13:43:14.160 3306-3306/com.parassidhu.pdfpin D/Data: /storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:43:14.160 3306-3306/com.parassidhu.pdfpin D/DataPath: file:///storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:43:14.160 3306-3306/com.parassidhu.pdfpin D/DataPath: Nakal
API28 的日志相同:
2019-08-02 13:55:07.853 5341-5341/com.parassidhu.pdfpin D/Data: /storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:55:07.853 5341-5341/com.parassidhu.pdfpin D/DataPath: file:///storage/emulated/0/Download/Nakal.pdf
2019-08-02 13:55:07.853 5341-5341/com.parassidhu.pdfpin D/DataPath: Nakal
由于没有错误,我正在摸不着头脑,因为可能出了什么问题。我在 Android Q 中阅读了有关 Scoped Storage 的内容,但这不适用于此处,因为我不是针对 Q。我在 Android Q 中阅读了其他行为更改,但 none 确实适用据我所知。
可能是什么问题?感谢阅读!
Uri.fromFile()
自 Android 7.0 以来已被有效禁止,因为它会触发 FileUriExposedException
.
在您的应用中使用 FileProvider
并 FileProvider.getUriForFile()
创建 Uri
以在您的 Intent
中使用。
感谢@CommonsWare的指点,我解决了这个问题。我做了两个更改:
对于 Android 7.0 及更高版本,我使用
FileProvider.getUriForFile()
而不是 @CommonsWare 建议的Uri.fromFile()
。而不是使用
setFlags()
(在Kotlin的语法中,它是intent.flags = <flag>
),我使用addFlags()
并传递Intent.FLAG_GRANT_READ_URI_PERMISSION
。
解释:
第一个更改确实是必要的,因为使用
Uri.fromFile()
方法导致FileUriExposedException
for Android 7.0+。不在应用程序中,因为单击快捷方式时,启动 activity 不属于我的应用程序。这就是为什么我抓不到它的原因。我猜这个变化是罪魁祸首。如果我们不添加给定的标志,则 PDF 打开 activity(或应用程序)没有读取文件内容(或 uri)的权限。这就是 activity 打开一秒钟然后关闭的原因,因为它无法读取文件。
关于 setFlags()
与 addFlags()
,因为 setFlags()
删除了现有的标志并添加了指定的标志,所以它不起作用。但是 addFlags()
保留现有的标志并添加指定的标志。因此 addFlags()
有效。