From 0f5bf13634c5943113d7b5fc728251a6f20e485c Mon Sep 17 00:00:00 2001 From: Thibault Deckers Date: Wed, 24 Nov 2021 11:16:16 +0900 Subject: [PATCH] support for kitkat (API 19) --- CHANGELOG.md | 1 + README.md | 7 ++- android/app/build.gradle | 4 +- android/app/src/main/AndroidManifest.xml | 16 ++---- .../channel/calls/AccessibilityHandler.kt | 2 +- .../aves/channel/calls/WindowHandler.kt | 2 +- .../streams/SettingsChangeStreamHandler.kt | 2 +- .../metadata/android/de/full_description.txt | 2 +- .../android/en-US/full_description.txt | 2 +- lib/model/availability.dart | 10 ++++ lib/model/settings/settings.dart | 4 +- lib/widgets/common/map/buttons.dart | 4 +- pubspec.lock | 50 ++++++++++++------- 13 files changed, 65 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8543f355d..b4bb5f9a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - add and remove tags to JPEG/GIF/PNG/TIFF images - French translation +- restored support for Android KitKat (without Google Maps) ## [v1.5.6] - 2021-11-12 diff --git a/README.md b/README.md index 4cfec3aa7..43e10ab02 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ It scans your media collection to identify **motion photos**, **panoramas** (aka **Navigation and search** is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from **API 20 to 31**, i.e. from Lollipop to S) with features such as **app shortcuts** and **global search** handling. It also works as a **media viewer and picker**. +Aves integrates with Android (from **API 19 to 31**, i.e. from KitKat to S) with features such as **app shortcuts** and **global search** handling. It also works as a **media viewer and picker**. ## Screenshots @@ -82,5 +82,10 @@ To run the app: # flutter run -t lib/main_play.dart --flavor play ``` +To run the app on API 19 emulators: +``` +# flutter run -t lib/main_play.dart --flavor play --enable-software-rendering +``` + [Version badge]: https://img.shields.io/github/v/release/deckerst/aves?include_prereleases&sort=semver [Build badge]: https://img.shields.io/github/workflow/status/deckerst/aves/Quality%20check diff --git a/android/app/build.gradle b/android/app/build.gradle index 69f477b13..5f39c6960 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -55,9 +55,9 @@ android { applicationId appId // minSdkVersion constraints: // - Flutter & other plugins: 16 - // - google_maps_flutter v2.0.5: 20 + // - google_maps_flutter v2.1.1: 20 // - Aves native: 19 - minSdkVersion 20 + minSdkVersion 19 targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0546ae2a0..90111d4fd 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -4,21 +4,12 @@ android:installLocation="auto"> - + + + diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt index 77b5e015b..ebd55045c 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/AccessibilityHandler.kt @@ -27,7 +27,7 @@ class AccessibilityHandler(private val activity: Activity) : MethodCallHandler { try { removed = Settings.Global.getFloat(activity.contentResolver, Settings.Global.TRANSITION_ANIMATION_SCALE) == 0f } catch (e: Exception) { - Log.w(LOG_TAG, "failed to get settings", e) + Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) } result.success(removed) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/WindowHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/WindowHandler.kt index 2494977f9..528e70941 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/WindowHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/WindowHandler.kt @@ -45,7 +45,7 @@ class WindowHandler(private val activity: Activity) : MethodCallHandler { try { locked = Settings.System.getInt(activity.contentResolver, Settings.System.ACCELEROMETER_ROTATION) == 0 } catch (e: Exception) { - Log.w(LOG_TAG, "failed to get settings", e) + Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) } result.success(locked) } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt index 26c15805a..60cb1f800 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/streams/SettingsChangeStreamHandler.kt @@ -56,7 +56,7 @@ class SettingsChangeStreamHandler(private val context: Context) : EventChannel.S } } catch (e: Exception) { - Log.w(LOG_TAG, "failed to get settings", e) + Log.w(LOG_TAG, "failed to get settings with error=${e.message}", null) } return changed } diff --git a/fastlane/metadata/android/de/full_description.txt b/fastlane/metadata/android/de/full_description.txt index 15d681520..8e7929a6f 100644 --- a/fastlane/metadata/android/de/full_description.txt +++ b/fastlane/metadata/android/de/full_description.txt @@ -2,4 +2,4 @@ Navigation und Suche ist ein wichtiger Bestandteil von Aves. Das Ziel besteht darin, dass Benutzer problemlos von Alben zu Fotos zu Tags zu Karten usw. wechseln können. -Aves lässt sich mit Android (von API 20 bis 31, d. h. von Lollipop bis S) mit Funktionen wie App-Verknüpfungen und globaler Suche integrieren. Es funktioniert auch als Medienbetrachter und -auswahl. \ No newline at end of file +Aves lässt sich mit Android (von API 19 bis 31, d. h. von KitKat bis S) mit Funktionen wie App-Verknüpfungen und globaler Suche integrieren. Es funktioniert auch als Medienbetrachter und -auswahl. \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index c7ccffdc9..8a74c8d0b 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -2,4 +2,4 @@ Navigation and search is an important part of Aves. The goal is for users to easily flow from albums to photos to tags to maps, etc. -Aves integrates with Android (from API 20 to 31, i.e. from Lollipop to S) with features such as app shortcuts and global search handling. It also works as a media viewer and picker. \ No newline at end of file +Aves integrates with Android (from API 19 to 31, i.e. from KitKat to S) with features such as app shortcuts and global search handling. It also works as a media viewer and picker. \ No newline at end of file diff --git a/lib/model/availability.dart b/lib/model/availability.dart index 828fda49e..2ba3c216f 100644 --- a/lib/model/availability.dart +++ b/lib/model/availability.dart @@ -1,6 +1,7 @@ import 'package:aves/model/settings/settings.dart'; import 'package:aves/theme/durations.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:github/github.dart'; @@ -17,6 +18,8 @@ abstract class AvesAvailability { Future get canLocatePlaces; + Future get canUseGoogleMaps; + Future get isNewVersionAvailable; } @@ -59,6 +62,13 @@ class LiveAvesAvailability implements AvesAvailability { @override Future get canLocatePlaces => Future.wait([isConnected, hasPlayServices]).then((results) => results.every((result) => result)); + // as of google_maps_flutter v2.1.1, minSDK is 20 because of default PlatformView usage, + // but using hybrid composition would make it usable on 19 too, cf https://github.com/flutter/flutter/issues/23728 + Future get _isUseGoogleMapRenderingSupported => DeviceInfoPlugin().androidInfo.then((androidInfo) => (androidInfo.version.sdkInt ?? 0) >= 20); + + @override + Future get canUseGoogleMaps => Future.wait([_isUseGoogleMapRenderingSupported, hasPlayServices]).then((results) => results.every((result) => result)); + @override Future get isNewVersionAvailable async { if (_isNewVersionAvailable != null) return SynchronousFuture(_isNewVersionAvailable!); diff --git a/lib/model/settings/settings.dart b/lib/model/settings/settings.dart index 62f76fd1c..25522d64f 100644 --- a/lib/model/settings/settings.dart +++ b/lib/model/settings/settings.dart @@ -152,8 +152,8 @@ class Settings extends ChangeNotifier { enableOverlayBlurEffect = performanceClass >= 29; // availability - final hasPlayServices = await availability.hasPlayServices; - if (hasPlayServices) { + final canUseGoogleMaps = await availability.canUseGoogleMaps; + if (canUseGoogleMaps) { infoMapStyle = EntryMapStyle.googleNormal; } else { final styles = EntryMapStyle.values.whereNot((v) => v.isGoogleMaps).toList(); diff --git a/lib/widgets/common/map/buttons.dart b/lib/widgets/common/map/buttons.dart index 0745868a2..dc5156dcd 100644 --- a/lib/widgets/common/map/buttons.dart +++ b/lib/widgets/common/map/buttons.dart @@ -135,8 +135,8 @@ class MapButtonPanel extends StatelessWidget { child: MapOverlayButton( icon: const Icon(AIcons.layers), onPressed: () async { - final hasPlayServices = await availability.hasPlayServices; - final availableStyles = EntryMapStyle.values.where((style) => !style.isGoogleMaps || hasPlayServices); + final canUseGoogleMaps = await availability.canUseGoogleMaps; + final availableStyles = EntryMapStyle.values.where((style) => !style.isGoogleMaps || canUseGoogleMaps); final preferredStyle = settings.infoMapStyle; final initialStyle = availableStyles.contains(preferredStyle) ? preferredStyle : availableStyles.first; final style = await showDialog( diff --git a/pubspec.lock b/pubspec.lock index 01702bd34..95ebebf7c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -119,14 +119,14 @@ packages: name: connectivity_plus url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" connectivity_plus_linux: dependency: transitive description: name: connectivity_plus_linux url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" connectivity_plus_macos: dependency: transitive description: @@ -140,7 +140,7 @@ packages: name: connectivity_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" connectivity_plus_web: dependency: transitive description: @@ -196,7 +196,7 @@ packages: name: dbus url: "https://pub.dartlang.org" source: hosted - version: "0.5.6" + version: "0.6.6" decorated_icon: dependency: "direct main" description: @@ -340,7 +340,7 @@ packages: name: flex_color_picker url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.2.0" fluster: dependency: "direct main" description: @@ -404,7 +404,7 @@ packages: name: flutter_plugin_android_lifecycle url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" flutter_staggered_animations: dependency: "direct main" description: @@ -468,7 +468,7 @@ packages: name: google_maps_flutter url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" google_maps_flutter_platform_interface: dependency: transitive description: @@ -573,7 +573,7 @@ packages: name: markdown url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.0.1" matcher: dependency: transitive description: @@ -629,7 +629,7 @@ packages: name: nm url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.4.1" node_preamble: dependency: transitive description: @@ -727,7 +727,7 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.2" path_provider_platform_interface: dependency: transitive description: @@ -741,14 +741,14 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" pdf: dependency: "direct main" description: name: pdf url: "https://pub.dartlang.org" source: hosted - version: "3.6.1" + version: "3.6.3" pedantic: dependency: transitive description: @@ -769,7 +769,7 @@ packages: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "8.2.6" + version: "8.3.0" permission_handler_platform_interface: dependency: transitive description: @@ -818,7 +818,7 @@ packages: name: printing url: "https://pub.dartlang.org" source: hosted - version: "5.6.0" + version: "5.6.3" process: dependency: transitive description: @@ -867,6 +867,20 @@ packages: name: shared_preferences url: "https://pub.dartlang.org" source: hosted + version: "2.0.9" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + shared_preferences_ios: + dependency: transitive + description: + name: shared_preferences_ios + url: "https://pub.dartlang.org" + source: hosted version: "2.0.8" shared_preferences_linux: dependency: transitive @@ -874,7 +888,7 @@ packages: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" shared_preferences_macos: dependency: transitive description: @@ -902,7 +916,7 @@ packages: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" shelf: dependency: transitive description: @@ -1084,7 +1098,7 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.0.12" + version: "6.0.15" url_launcher_linux: dependency: transitive description: @@ -1175,7 +1189,7 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.2.10" + version: "2.3.0" wkt_parser: dependency: transitive description: