diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 0eaf22d..dd328dc 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -78,7 +78,7 @@ jobs: "ndk;27.0.12077973" "cmake;3.22.1" > /dev/null - name: Build and unit test - run: ./gradlew assembleDebug :app:testDebugUnitTest --stacktrace + run: ./gradlew assembleDebug :app:testDebugUnitTest :app:lintVitalRelease --stacktrace - name: Upload debug APK uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8bcb6bb..68d65b6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -80,6 +80,12 @@ android { } } + lint { + // Calling an API newer than minSdk crashes on older TVs and cars (1.4.0 did on any key + // before Android 12); lintVital, which CI and every release build run, stops on it. + fatal += "NewApi" + } + buildTypes { debug { // Installs beside the release app, with the simulated sender (src/debug) for tests. diff --git a/app/src/main/java/com/weenas/castbay/MainActivity.kt b/app/src/main/java/com/weenas/castbay/MainActivity.kt index a78f5e1..0d760de 100644 --- a/app/src/main/java/com/weenas/castbay/MainActivity.kt +++ b/app/src/main/java/com/weenas/castbay/MainActivity.kt @@ -47,7 +47,7 @@ class MainActivity : ComponentActivity() { } // Media keys (a steering wheel's too) always work and don't wake the screen saver; // any other key wakes it, and does nothing else. - if (!KeyEvent.isMediaSessionKey(event.keyCode)) { + if (event.keyCode !in MEDIA_KEYS) { if (event.action == KeyEvent.ACTION_DOWN) { val asleep = viewModel.screenSaverOn viewModel.noteActivity() @@ -146,3 +146,14 @@ private fun Screens() { DeviceRequestDialog(deviceRequest, onAnswer = viewModel::answerDeviceRequest, onDismiss = viewModel::dismissDeviceRequest) } } + +/** + * The keys a media session handles (as KeyEvent.isMediaSessionKey, which is Android 12+: before + * that, calling it crashed on any key). + */ +private val MEDIA_KEYS = setOf( + KeyEvent.KEYCODE_MEDIA_PLAY, KeyEvent.KEYCODE_MEDIA_PAUSE, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, + KeyEvent.KEYCODE_MUTE, KeyEvent.KEYCODE_HEADSETHOOK, KeyEvent.KEYCODE_MEDIA_STOP, + KeyEvent.KEYCODE_MEDIA_NEXT, KeyEvent.KEYCODE_MEDIA_PREVIOUS, KeyEvent.KEYCODE_MEDIA_REWIND, + KeyEvent.KEYCODE_MEDIA_RECORD, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD +) diff --git a/app/src/main/java/com/weenas/castbay/ui/screen/ChangelogScreen.kt b/app/src/main/java/com/weenas/castbay/ui/screen/ChangelogScreen.kt index 298cf70..41874f6 100644 --- a/app/src/main/java/com/weenas/castbay/ui/screen/ChangelogScreen.kt +++ b/app/src/main/java/com/weenas/castbay/ui/screen/ChangelogScreen.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration +import androidx.core.os.ConfigurationCompat import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -35,7 +36,8 @@ fun ChangelogScreen(viewModel: AirPlayViewModel) { val context = LocalContext.current val update by viewModel.update.collectAsState() val installed = remember { AppVersion.name(context) } - val chinese = LocalConfiguration.current.locales[0].language == "zh" + // The compat form: Configuration.locales is Android 7+. + val chinese = ConfigurationCompat.getLocales(LocalConfiguration.current)[0]?.language == "zh" val current = update ?: return val notes = current.notesSince(installed)