Ярлык не запускает файл в Android Q

Мое 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)
            pdfIntent.setDataAndType(Uri.fromFile(file), "application/pdf")

            Log.d("DataPath", Uri.fromFile(file).toString())
            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

Так как ошибки нет, я почесал голову, что могло пойти не так. Я читал о Scoped Storage в Android Q, но здесь это не касается, так как я не нацеливаюсь на Q. Я читал о других изменениях поведения в Android Q, но ни одно из них не применимо, насколько я читаю.

В чем может быть проблема? Спасибо за чтение!

0 ответов

Uri.fromFile() был эффективно запрещен с Android 7.0, так как запускает FileUriExposedException.

Использовать FileProvider в вашем приложении и FileProvider.getUriForFile() создать Uri использовать в вашем Intent.

Благодаря подсказке @CommonsWare я решил проблему. Я внес два изменения:

  1. Для Android 7.0 и выше я использовал FileProvider.getUriForFile() вместо того Uri.fromFile() как предлагает @CommonsWare.

  2. Вместо того, чтобы использовать setFlags() (В синтаксисе Котлина это 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() работал.

Другие вопросы по тегам