platform upgrades

This commit is contained in:
2026-09-02 20:17:17 +02:00
parent 71839d0848
commit f19f212fb4
12 changed files with 51 additions and 56 deletions
+1
View File
@@ -11,3 +11,4 @@ GeneratedPluginRegistrant.java
key.properties
**/*.keystore
**/*.jks
.kotlin/
+6 -6
View File
@@ -33,10 +33,6 @@ android {
coreLibraryDesugaringEnabled true
}
kotlinOptions {
jvmTarget = '17'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
@@ -47,7 +43,6 @@ android {
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}
buildTypes {
@@ -59,12 +54,17 @@ android {
}
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
}
}
flutter {
source '../..'
}
dependencies {
implementation 'com.android.support:multidex:2.0.1'
// Same version as workmanager_android pins — needed to enqueue its
// BackgroundWorker from native widget code (the plugin uses
// `implementation`, so androidx.work is not exposed transitively).
@@ -1,25 +0,0 @@
// Generated file.
//
// If you wish to remove Flutter's multidex support, delete this entire file.
//
// Modifications to this file should be done in a copy under a different name
// as this file may be regenerated.
package io.flutter.app;
import android.app.Application;
import android.content.Context;
import androidx.annotation.CallSuper;
import androidx.multidex.MultiDex;
/**
* Extension of {@link android.app.Application}, adding multidex support.
*/
public class FlutterMultiDexApplication extends Application {
@Override
@CallSuper
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
}
+18 -3
View File
@@ -5,10 +5,25 @@ allprojects {
}
}
rootProject.buildDir = '../build'
rootProject.layout.buildDirectory = file('../build')
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
project.layout.buildDirectory = rootProject.layout.buildDirectory.dir(project.name)
}
// AGP 9 enables built-in Kotlin, but Flutter's migrator pins
// android.builtInKotlin=false while the plugin ecosystem catches up. Most
// plugins honour that flag and fall back to KGP themselves; file_picker and
// background_downloader only check the AGP major version and silently skip
// applying KGP, which leaves their Kotlin sources uncompiled (missing
// FilePickerPlugin/BackgroundDownloaderPlugin at link time). Apply KGP for
// them as soon as AGP is on the project, i.e. before their android {} block
// runs. Drop this once both plugins ship a builtInKotlin-aware build script.
gradle.beforeProject { sub ->
if (!(sub.name in ['file_picker', 'background_downloader'])) return
sub.plugins.withId('com.android.library') {
sub.pluginManager.apply('org.jetbrains.kotlin.android')
}
}
// Pin every Android subproject to JVM 17 so plugins that ship Kotlin sources
// compiled with a higher target (e.g. receive_sharing_intent at 21) or stale
// Java compatibility (e.g. home_widget at 1.8) don't break the build under
@@ -42,5 +57,5 @@ subprojects {
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
delete rootProject.layout.buildDirectory
}
+2 -6
View File
@@ -1,10 +1,6 @@
org.gradle.jvmargs=-Xmx4G
android.useAndroidX=true
android.enableJetifier=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+3 -3
View File
@@ -19,9 +19,9 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.13.2' apply false
id "com.android.library" version '8.13.2' apply false
id "org.jetbrains.kotlin.android" version "2.2.20" apply false
id "com.android.application" version '9.1.0' apply false
id "com.android.library" version '9.1.0' apply false
id "org.jetbrains.kotlin.android" version "2.4.0" apply false
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.10.0'
}
+3 -2
View File
@@ -343,7 +343,8 @@ class PushRegistration {
/// transient plugin/platform hiccup never silently disables push (the OS
/// simply won't show notifications until the user decides).
static bool isPermissionUsable(AuthorizationStatus status) =>
status != AuthorizationStatus.denied;
status != AuthorizationStatus.denied &&
status != AuthorizationStatus.deniedPermanently;
/// Requests the OS notification permission (covers iOS + Android 13) and
/// returns whether registration should proceed. Errors from the plugin are
@@ -365,7 +366,7 @@ class PushRegistration {
try {
final settings = await FirebaseMessaging.instance
.getNotificationSettings();
return settings.authorizationStatus == AuthorizationStatus.denied;
return !isPermissionUsable(settings.authorizationStatus);
} on Object {
return false;
}
+1
View File
@@ -148,6 +148,7 @@ Future<PushCheck> _osPermission() async {
case AuthorizationStatus.provisional:
return PushCheck.ok;
case AuthorizationStatus.denied:
case AuthorizationStatus.deniedPermanently:
return PushCheck.fail;
case AuthorizationStatus.notDetermined:
return PushCheck.unknown;
+1 -1
View File
@@ -203,7 +203,7 @@ class AppModule {
var moveIndex = 0;
return [
for (final m in effective)
displayedSet.contains(m) ? moved[moveIndex++] : m,
if (displayedSet.contains(m)) moved[moveIndex++] else m,
];
}
+4 -4
View File
@@ -20,7 +20,7 @@ dependencies:
async: ^2.11.0
badges: ^3.1.2
cached_network_image: ^3.4.1
cached_network_image: ^4.0.0
# Grapheme-cluster iteration for emoji-only message detection
# (lib/utils/emoji_detection.dart). Already present transitively via flutter.
characters: ^1.4.0
@@ -44,7 +44,7 @@ dependencies:
flutter_bloc: ^9.0.0
flutter_secure_storage: ^10.0.0
home_widget: ^0.9.3
workmanager: ^0.9.0+3
workmanager: ^0.10.9
intl: ^0.20.2
flutter_linkify: ^6.0.0
linkify: ^5.0.0
@@ -96,7 +96,7 @@ dependencies:
background_downloader: ^9.5.5
# Opens the OS notification settings for this app (iOS + Android) when the
# user declined the permission and wants to enable it later.
app_settings: ^7.0.0
app_settings: ^9.0.0
flutter_layout_grid: ^2.0.8
flutter_markdown_plus: ^1.0.12
# Underlying parser for flutter_markdown_plus; imported directly to build the
@@ -114,7 +114,7 @@ dev_dependencies:
flutter_launcher_icons: ^0.14.3
build_runner: ^2.10.5
freezed: ^3.2.4
freezed: ^4.0.0
json_serializable: ^6.11.4
flutter_lints: ^6.0.0
+8 -2
View File
@@ -5,10 +5,16 @@ import 'package:marianum_mobile/push/push_registration.dart';
void main() {
group('PushRegistration.isPermissionUsable', () {
test('explicit denial blocks registration', () {
for (final status in [
AuthorizationStatus.denied,
AuthorizationStatus.deniedPermanently,
]) {
expect(
PushRegistration.isPermissionUsable(AuthorizationStatus.denied),
PushRegistration.isPermissionUsable(status),
isFalse,
reason: '$status should block registration',
);
}
});
test('all other statuses allow registration', () {
@@ -28,7 +34,7 @@ void main() {
test('covers every AuthorizationStatus value', () {
// Guard: if firebase_messaging ever adds a status, revisit the gate.
expect(AuthorizationStatus.values, hasLength(4));
expect(AuthorizationStatus.values, hasLength(5));
});
});
}