快捷方式不会在Android Q中启动文件

时间:2019-08-02 08:27:48

标签: android android-shortcutmanager

编辑:

单击固定的快捷方式时,我进入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”会打开,但是实际文件显示为黑色,在一秒钟之内,该应用程序就会关闭。

OLD:

我的Android应用程序的目标是API级别28。它将PDF文件的快捷方式固定到主屏幕,然后单击图标显然会打开文件。直到Android Pie,它的工作情况都还不错。但是,当我在API 29上对其进行测试时,单击该图标将打开PDF Viewer,并强制关闭而没有错误。这是相关的代码。

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

API 28的日志相同:

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中的作用域存储的信息,但由于我不是针对Q的,因此不适用于此处。我已经阅读了有关Android Q中其他行为的更改,但据我所知,没有一个适用。

可能是什么问题?感谢您的阅读!

2 个答案:

答案 0 :(得分:0)

Uri.fromFile()自Android 7.0起已被有效禁止,因为它会触发FileUriExposedException

在应用中使用FileProvider,在FileProvider.getUriForFile()中使用Uri创建Intent

答案 1 :(得分:0)

由于@CommonsWare的提示,我解决了这个问题。我做了两个更改:

  1. 对于Android 7.0及更高版本,我使用FileProvider.getUriForFile()代替了@CommonsWare建议的Uri.fromFile()

  2. 我没有使用setFlags()(按照Kotlin的语法,它是intent.flags = <flag>),而是使用addFlags()并传递了Intent.FLAG_GRANT_READ_URI_PERMISSION

说明:

  1. 由于使用Uri.fromFile()方法会导致FileUriExposedException对于Android 7.0+的使用,因此确实有必要进行第一个更改。由于单击快捷方式后,已开始的活动不属于我的应用,因此不在该应用中。这就是为什么我抓不到它的原因。

  2. 我猜这是罪魁祸首。如果我们不添加给定标志,则PDF打开活动(或应用程序)无权读取文件内容(或uri)。这就是为什么该活动打开一秒钟然后关闭的原因,因为它无法读取文件。

关于setFlags()addFlags(),由于setFlags()删除了现有的标志并添加了指定的标志,因此它不起作用。但是addFlags()保留现有标志并添加指定的标志。因此addFlags()起作用了。