Рассмотрите возможность добавления объявления запросов в свой манифест при вызове этого метода при использовании намерения.resolveActivity в Android 11.

У меня есть функция расширения для открытия намерения для моих действий:

fun Activity.openIntent(action: String?, type: String?, uri: Uri?) {
    Intent()
        .apply {
            action?.let { this.action = it }
            uri?.let { this.data = it }
            type?.let { this.type = it }
        }
        .also { intent ->
            packageManager?.let {
                if (intent.resolveActivity(it) != null)
                    startActivity(intent)
                else
                    showToast(R.string.application_not_found)
            }
        }
}

Моему targetSdkVersion 30. Это дает мне предупреждение в intent.resolveActivity(it):

Рассмотрите возможность добавления объявления запросов в манифест при вызове этого метода.

Итак, что мне делать, чтобы решить это предупреждение?


person Saman Sattari    schedule 21.11.2020    source источник


Ответы (3)


Самое простое решение — избавиться от resolveActivity(). Заменять:

            packageManager?.let {
                if (intent.resolveActivity(it) != null)
                    startActivity(intent)
                else
                    showToast(R.string.application_not_found)
            }

с:

            try {
                startActivity(intent)
            } catch (ex: ActivityNotFoundException) {
                showToast(R.string.application_not_found)
            }

Это даст вам тот же результат с немного лучшей производительностью, и это избавит вас от предупреждения.

Другой вариант — добавить разрешение QUERY_ALL_PACKAGES. Это может привести к тому, что вас забанят в Play Store.

В противном случае вам потребуется:

  • Составьте список всех возможных openIntent() вызовов, которые может сделать ваше приложение.

  • Добавьте в манифест элемент <queries>, в котором перечислены все те возможные Intent структуры, которые вы хотите использовать с resolveActivity()

  • Периодически повторяйте этот процесс, если вы добавите новые сценарии для openIntent().

person CommonsWare    schedule 21.11.2020
comment
The application could not be installed: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED. Я получаю эту ошибку, если добавляю элемент запросов в манифест. gist.github.com/sudhirkhanger/fbb613b38f25c44ad0342a237a2d06e6 - person Sudhir Singh Khanger; 24.02.2021
comment
@SudhirSinghKhanger: none не является допустимым типом MIME, поэтому этот элемент не помогает. Попробуйте удалить его. - person CommonsWare; 24.02.2021
comment
ты прав. Спасибо за вашу помощь. - person Sudhir Singh Khanger; 25.02.2021

Таким образом, начиная с Android 11 (т. Е. Если ваше приложение нацелено на Android 11), не все приложения будут видны вашему приложению. Некоторые приложения видимы по умолчанию, но для доступа к другим приложения через ваше приложение, вам придется объявить queries в своем манифесте, иначе ваше приложение не сможет получить к ним доступ. Вы можете прочитать об этом здесь.

Поэтому, если ваше приложение нацелено на Android 11 и должно получить доступ к приложению, которое может быть невидимым по умолчанию, вы захотите добавить для них queries в файле манифеста.

В вашем случае это предупреждение неприменимо, поскольку я считаю, что вы используете неявные намерения для открытия других приложений. Используя неявные намерения, можно получить доступ к другим приложениям независимо от их видимости. Если ваше приложение предназначено для Android 10 или более ранней версии, вы можете отключить предупреждение, так как все приложения видны по умолчанию.

Чтобы подавить предупреждение о ворсе, вы можете:

  1. Добавьте аннотацию подавления, например:
@SuppressLint("QueryPermissionsNeeded")
fun Activity.openIntent(action: String?, type: String?, uri: Uri?): Activity {
  1. Добавьте следующее в свой блок android в файл градиента сборки модуля приложения:
lintOptions {
    ignore "QueryPermissionsNeeded"
}
person Keyser Söze    schedule 21.11.2020
comment
Похоже, что только блок lintOptions выполняет эту работу. Спасибо! - person Itay Feldman; 25.01.2021
comment
Оба делают работу. Вы можете использовать любой из двух. - person Keyser Söze; 25.01.2021
comment
это предупреждение неприменимо, поскольку я полагаю, что вы используете неявные намерения для открытия других приложений - предупреждение исходит от вызова resolveActivity(), для работы которого требуется элемент <queries>. - person CommonsWare; 31.01.2021
comment
Да, это то, что я написал. Хотя это касается только явных намерений и приложений, нацеленных на API 30, как указано в официальной документации Android. Я предоставил подходящие ссылки для того же в своем ответе - person Keyser Söze; 31.01.2021
comment
Допустим, вы создаете приложение для Android 11 и хотите явно открыть приложение WhatsApp, но не добавляете для него query в манифесте. Если мы обернем вызов startActivity в блок try-catch, то управление всегда будет падать на блок catch на устройстве Android 11, даже если на устройстве установлено приложение WhatsApp. - person Keyser Söze; 31.01.2021

Заменять

if (intent.resolveActivity(it) != null)

с

if (it.resolveActivity(intent, 0) != null)

и предупреждение исчезнет.

person Tatsuya Fujisaki    schedule 20.03.2021
comment
Какой объект it? - person azizbekian; 15.06.2021