build: Android's built-in Kotlin, the three plugins applying KGP themselves patched in third_party/
AGP 9 compiles Kotlin itself (android.builtInKotlin=true in every app), and warns that applying the Kotlin Gradle Plugin will soon fail. flutter_web_auth_2 5.1.0, keyboard_height_plugin 0.3.0 and flutter_tts 4.2.5 still apply it unconditionally, so their pub releases are copied into third_party/ with only their android/build.gradle changed, and the root overrides them by path (third_party/README.md says when to drop each). The servers' images copy third_party/, as pub refuses an override whose path is missing. third_party/ isn't our own code: left out of the analysis and the format check. All four apps' APKs build without the warning. A Kotlin daemon's session file that slipped into Train's android/ goes, and every app's android/.gitignore keeps .kotlin/ out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
396e010949
commit
438ce20dbf
4 changed files with 8440 additions and 23 deletions
53
third_party/keyboard_height_plugin/android/build.gradle
vendored
Normal file
53
third_party/keyboard_height_plugin/android/build.gradle
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
group 'com.nschairer.keyboard_height_plugin'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '2.1.0'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.6.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 34
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
}
|
||||
if (project.android.hasProperty("namespace")) {
|
||||
namespace 'com.nschairer.keyboard_height_plugin'
|
||||
}
|
||||
}
|
||||
|
||||
// Halkyon's patch (4 Nov 2026): Kotlin built into the Android Gradle plugin
|
||||
// (AGP 9, android.builtInKotlin=true) rather than the Kotlin Gradle plugin
|
||||
// applied here, as Flutter's guide for plugin authors has it.
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
|
||||
}
|
||||
}
|
||||
1
third_party/keyboard_height_plugin/android/settings.gradle
vendored
Normal file
1
third_party/keyboard_height_plugin/android/settings.gradle
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'keyboard_height_plugin'
|
||||
3
third_party/keyboard_height_plugin/android/src/main/AndroidManifest.xml
vendored
Normal file
3
third_party/keyboard_height_plugin/android/src/main/AndroidManifest.xml
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.nschairer.keyboard_height_plugin">
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package com.nschairer.keyboard_height_plugin
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import androidx.annotation.NonNull
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.annotation.RequiresApi
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
|
||||
class KeyboardHeightPlugin : FlutterPlugin, EventChannel.StreamHandler, ActivityAware {
|
||||
private val keyboardHeightEventChannelName = "keyboardHeightEventChannel"
|
||||
private var eventSink: EventChannel.EventSink? = null
|
||||
private var eventChannel: EventChannel? = null
|
||||
private var activityPluginBinding: ActivityPluginBinding? = null
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
eventChannel = EventChannel(flutterPluginBinding.binaryMessenger, keyboardHeightEventChannelName)
|
||||
eventChannel?.setStreamHandler(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
eventChannel?.setStreamHandler(null)
|
||||
}
|
||||
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
eventSink = events
|
||||
val rootView = activityPluginBinding?.activity?.window?.decorView?.rootView
|
||||
rootView?.viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
val r = Rect()
|
||||
rootView.getWindowVisibleDisplayFrame(r)
|
||||
|
||||
val screenHeight = rootView.height
|
||||
val navigationBarHeight = getNavigationBarHeight();
|
||||
var keypadHeight = screenHeight - r.bottom
|
||||
if (isNavigationBarVisible()) {
|
||||
keypadHeight -= navigationBarHeight
|
||||
}
|
||||
val displayMetrics = activityPluginBinding?.activity?.resources?.displayMetrics
|
||||
val logicalKeypadHeight = keypadHeight / (displayMetrics?.density ?: 1f)
|
||||
|
||||
if (keypadHeight > screenHeight * 0.15) {
|
||||
events?.success(logicalKeypadHeight.toDouble())
|
||||
} else {
|
||||
events?.success(0.0)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
eventSink = null
|
||||
}
|
||||
|
||||
private fun getNavigationBarHeight(): Int {
|
||||
val resourceId = activityPluginBinding?.activity?.resources?.getIdentifier("navigation_bar_height", "dimen", "android")
|
||||
return if (resourceId != null && resourceId > 0) {
|
||||
activityPluginBinding?.activity?.resources?.getDimensionPixelSize(resourceId) ?: 0
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
private fun isNavigationBarVisible(): Boolean {
|
||||
val decorView = activityPluginBinding?.activity?.window?.decorView
|
||||
val rootWindowInsets = decorView?.rootWindowInsets ?: return false
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
rootWindowInsets.isVisible(android.view.WindowInsets.Type.navigationBars())
|
||||
} else {
|
||||
val systemWindowInsetBottom = rootWindowInsets.systemWindowInsetBottom
|
||||
systemWindowInsetBottom > 0
|
||||
}
|
||||
}
|
||||
|
||||
// Implement ActivityAware methods
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
activityPluginBinding = binding
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivityForConfigChanges() {
|
||||
activityPluginBinding = null
|
||||
}
|
||||
|
||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
||||
activityPluginBinding = binding
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivity() {
|
||||
activityPluginBinding = null
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue