Как обращаться с `устарело. Устарело в Java`?

Код, который я хочу использовать:

window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED)

Существует FLAG_SHOW_WHEN_LOCKED , который устарел в API 27, и его альтернатива setShowWhenLocked добавлена ​​в API 27. Как мне правильно его использовать, если minSdk в моем проекте 21, а targetSdk 33?

Я получаю предупреждение is deprecated. Deprecated in Java
Даже если я справлюсь с этим следующим образом:

if (Build.VERSION.SDK_INT >= 27) {
    setShowWhenLocked(true)
    setTurnScreenOn(true)
} else {
    window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}

Я все еще получаю предупреждение. Как правильно поддерживать как старый, так и новый API?

5
0
230
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

TLDR

1. Используйте разный код для разных версий API.
2. Игнорируйте/отключайте это предупреждение, если вы правильно обрабатываете все версии API, для которых создано ваше приложение
3. Если есть новая альтернатива, которая работает на всех уровнях API - используйте ее

Инструкция

  1. Используйте Build.VERSION.SDK_INT в условии, чтобы вести себя соответственно SDK_INT
  2. Используйте setshowwhenlocked, если SDK_INT>=27 и FLAG_SHOW_WHEN_LOCKED, если SDK_INT<27
  3. Подавить предупреждение

Пример с FLAG_SHOW_WHEN_LOCKED/setShowWhenLocked

if (Build.VERSION.SDK_INT >= 27) {
    setShowWhenLocked(true)
    setTurnScreenOn(true)
} else {
    @Suppress("DEPRECATION")
    window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
            WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
}

Но почему мы должны превзойти предупреждение?

Предупреждение существует только потому, что @Deprecated API не имеют метаданных, которые указывали бы, в каком SDK они устарели. Как вы можете видеть в этой проблеме. Мы можем подавить ошибку, потому что мы правильно обработали как старый API (5-27), так и новый API (27>).

Предупреждение

Не подавляйте эти предупреждения, если код не обрабатывается должным образом с использованием условий if, где используется правильный API.

Пример того, как нельзя делать

@Suppress("DEPRECATION")
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
        WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)

Ваш minSdk равен 21, а targetSdk равен 33. Этот код будет работать на устройствах с API 5-27 (Android 5 - Android 8.1), но не будет работать на новых устройствах. Вы должны правильно обрабатывать оба условия.

Пример с Vibrator

Старый способ получить вибратор

context.getSystemService(VIBRATOR_SERVICE) as Vibrator

Новый способ получить вибратор

val vibrator = if (Build.VERSION.SDK_INT >= 31) {
    val vibratorManager =
        context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
    vibratorManager.defaultVibrator
} else {
    @Suppress("DEPRECATION")
    context.getSystemService(VIBRATOR_SERVICE) as Vibrator
}
Will show you the warning `'VIBRATOR_SERVICE: String' is deprecated. Deprecated in Java`. Go to the [documentation](https://developer.android.com/reference/kotlin/android/content/Context#vibrator_service) and see that this constant can be used in the API 1-31 so we must. And in both IDE and documentation there is the info about the alternative: `Deprecated: Use android.os.VibratorManager to retrieve the default system vibrator.`. As you can see the [VibrationManager](https://developer.android.com/reference/kotlin/android/os/VibratorManager) is added in the API 31 therefore we must write the different code for different sdk versions

Если альтернатива обратно совместима

Если альтернатива обратно совместима, вы можете просто использовать ее вместо старого способа.

Пример

Если вы наследуете AppCompatActivity в своей деятельности:

class SaveMyLifeActivity : AppCompatActivity()

Вы можете встретить предупреждение startActivityForResult(Intent!, Int): Unit' is deprecated. Deprecated in Java, если позвоните startActivityForResult:

val intent = Intent(this, SaveMyLifeActivity::class.java)
startActivityForResult(intent, 0)

Вы можете нажать Alt + Q (привязка клавиш по умолчанию), чтобы увидеть Context info (это называется так в AndroidStudio, если вы проверяете свою раскладку) или использовать веб-сайт, см. документацию Обратите внимание на слова о том, что этот метод устарел, и вместо него вы должны использовать registerForActivityResult. Этот метод сейчас можно вызывать в любой версии, в документации нет Added/Deprecated "раздела".

Вопрос: Как вы нашли эту документацию? Я гуглю AppCombatActivity startActivityForResult и нахожу эту документацию. Ни слова о startActivityForResult.
Ответ: Откройте контекстную информацию об этом методе в IDE (Alt+Q) и посмотрите внизу Context info . Существует имя класса, в котором находится этот метод (ComponentActivity). Вы должны Google ComponentActivity startActivityForResult вместо AppCombatActivity startActivityForResult

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