map style check
This commit is contained in:
parent
068f4d499a
commit
8ced682bfd
15 changed files with 75 additions and 65 deletions
|
@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
- upgraded Flutter to stable v3.0.1
|
- upgraded Flutter to stable v3.0.1
|
||||||
- stretching overscroll effect
|
- stretching overscroll effect
|
||||||
|
- disabled Google Maps layer on Android Lollipop
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,6 @@ class DeviceHandler(private val context: Context) : MethodCallHandler {
|
||||||
"canPinShortcut" to ShortcutManagerCompat.isRequestPinShortcutSupported(context),
|
"canPinShortcut" to ShortcutManagerCompat.isRequestPinShortcutSupported(context),
|
||||||
"canPrint" to (sdkInt >= Build.VERSION_CODES.KITKAT),
|
"canPrint" to (sdkInt >= Build.VERSION_CODES.KITKAT),
|
||||||
"canRenderFlagEmojis" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP),
|
"canRenderFlagEmojis" to (sdkInt >= Build.VERSION_CODES.LOLLIPOP),
|
||||||
// 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 API 19 too,
|
|
||||||
// cf https://github.com/flutter/flutter/issues/23728
|
|
||||||
"canRenderGoogleMaps" to (sdkInt >= Build.VERSION_CODES.KITKAT_WATCH),
|
|
||||||
"showPinShortcutFeedback" to (sdkInt >= Build.VERSION_CODES.O),
|
"showPinShortcutFeedback" to (sdkInt >= Build.VERSION_CODES.O),
|
||||||
"supportEdgeToEdgeUIMode" to (sdkInt >= Build.VERSION_CODES.Q),
|
"supportEdgeToEdgeUIMode" to (sdkInt >= Build.VERSION_CODES.Q),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/enums/map_style.dart';
|
||||||
import 'package:aves_services_platform/aves_services_platform.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
|
import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
@ -10,7 +11,7 @@ abstract class AvesAvailability {
|
||||||
|
|
||||||
Future<bool> get canLocatePlaces;
|
Future<bool> get canLocatePlaces;
|
||||||
|
|
||||||
Future<bool> get canUseDeviceMaps;
|
List<EntryMapStyle> get mapStyles;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LiveAvesAvailability implements AvesAvailability {
|
class LiveAvesAvailability implements AvesAvailability {
|
||||||
|
@ -42,11 +43,11 @@ class LiveAvesAvailability implements AvesAvailability {
|
||||||
// local geocoding with `geocoder` seems to require Google Play Services
|
// local geocoding with `geocoder` seems to require Google Play Services
|
||||||
// what about devices with Huawei Mobile Services?
|
// what about devices with Huawei Mobile Services?
|
||||||
@override
|
@override
|
||||||
Future<bool> get canLocatePlaces => Future.wait<bool>([
|
Future<bool> get canLocatePlaces async => mobileServices.isServiceAvailable && await isConnected;
|
||||||
isConnected,
|
|
||||||
PlatformMobileServices().isServiceAvailable(),
|
|
||||||
]).then((results) => results.every((result) => result));
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> get canUseDeviceMaps async => device.canRenderGoogleMaps && await PlatformMobileServices().isServiceAvailable();
|
List<EntryMapStyle> get mapStyles => [
|
||||||
|
...mobileServices.mapStyles,
|
||||||
|
...EntryMapStyle.values.where((v) => !v.needMobileService),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ final Device device = Device._private();
|
||||||
|
|
||||||
class Device {
|
class Device {
|
||||||
late final String _userAgent;
|
late final String _userAgent;
|
||||||
late final bool _canGrantDirectoryAccess, _canPinShortcut, _canPrint, _canRenderFlagEmojis, _canRenderGoogleMaps;
|
late final bool _canGrantDirectoryAccess, _canPinShortcut, _canPrint, _canRenderFlagEmojis;
|
||||||
late final bool _showPinShortcutFeedback, _supportEdgeToEdgeUIMode;
|
late final bool _showPinShortcutFeedback, _supportEdgeToEdgeUIMode;
|
||||||
|
|
||||||
String get userAgent => _userAgent;
|
String get userAgent => _userAgent;
|
||||||
|
@ -18,8 +18,6 @@ class Device {
|
||||||
|
|
||||||
bool get canRenderFlagEmojis => _canRenderFlagEmojis;
|
bool get canRenderFlagEmojis => _canRenderFlagEmojis;
|
||||||
|
|
||||||
bool get canRenderGoogleMaps => _canRenderGoogleMaps;
|
|
||||||
|
|
||||||
bool get showPinShortcutFeedback => _showPinShortcutFeedback;
|
bool get showPinShortcutFeedback => _showPinShortcutFeedback;
|
||||||
|
|
||||||
bool get supportEdgeToEdgeUIMode => _supportEdgeToEdgeUIMode;
|
bool get supportEdgeToEdgeUIMode => _supportEdgeToEdgeUIMode;
|
||||||
|
@ -35,7 +33,6 @@ class Device {
|
||||||
_canPinShortcut = capabilities['canPinShortcut'] ?? false;
|
_canPinShortcut = capabilities['canPinShortcut'] ?? false;
|
||||||
_canPrint = capabilities['canPrint'] ?? false;
|
_canPrint = capabilities['canPrint'] ?? false;
|
||||||
_canRenderFlagEmojis = capabilities['canRenderFlagEmojis'] ?? false;
|
_canRenderFlagEmojis = capabilities['canRenderFlagEmojis'] ?? false;
|
||||||
_canRenderGoogleMaps = capabilities['canRenderGoogleMaps'] ?? false;
|
|
||||||
_showPinShortcutFeedback = capabilities['showPinShortcutFeedback'] ?? false;
|
_showPinShortcutFeedback = capabilities['showPinShortcutFeedback'] ?? false;
|
||||||
_supportEdgeToEdgeUIMode = capabilities['supportEdgeToEdgeUIMode'] ?? false;
|
_supportEdgeToEdgeUIMode = capabilities['supportEdgeToEdgeUIMode'] ?? false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ extension ExtraEntryMapStyle on EntryMapStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get needDeviceService {
|
bool get needMobileService {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case EntryMapStyle.osmHot:
|
case EntryMapStyle.osmHot:
|
||||||
case EntryMapStyle.stamenToner:
|
case EntryMapStyle.stamenToner:
|
||||||
|
|
|
@ -12,7 +12,6 @@ import 'package:aves/model/source/enums.dart';
|
||||||
import 'package:aves/services/accessibility_service.dart';
|
import 'package:aves/services/accessibility_service.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves_map/aves_map.dart';
|
import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:aves_services_platform/aves_services_platform.dart';
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
@ -165,11 +164,11 @@ class Settings extends ChangeNotifier {
|
||||||
enableOverlayBlurEffect = performanceClass >= 29;
|
enableOverlayBlurEffect = performanceClass >= 29;
|
||||||
|
|
||||||
// availability
|
// availability
|
||||||
final isDeviceMapAvailable = await availability.canUseDeviceMaps;
|
final defaultMapStyle = mobileServices.defaultMapStyle;
|
||||||
if (isDeviceMapAvailable) {
|
if (mobileServices.mapStyles.contains(defaultMapStyle)) {
|
||||||
infoMapStyle = PlatformMobileServices().defaultMapStyle;
|
infoMapStyle = defaultMapStyle;
|
||||||
} else {
|
} else {
|
||||||
final styles = EntryMapStyle.values.whereNot((v) => v.needDeviceService).toList();
|
final styles = EntryMapStyle.values.whereNot((v) => v.needMobileService).toList();
|
||||||
infoMapStyle = styles[Random().nextInt(styles.length)];
|
infoMapStyle = styles[Random().nextInt(styles.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +515,11 @@ class Settings extends ChangeNotifier {
|
||||||
|
|
||||||
// info
|
// info
|
||||||
|
|
||||||
EntryMapStyle get infoMapStyle => getEnumOrDefault(infoMapStyleKey, SettingsDefaults.infoMapStyle, EntryMapStyle.values);
|
EntryMapStyle get infoMapStyle {
|
||||||
|
final preferred = getEnumOrDefault(infoMapStyleKey, SettingsDefaults.infoMapStyle, EntryMapStyle.values);
|
||||||
|
final available = availability.mapStyles;
|
||||||
|
return available.contains(preferred) ? preferred : available.first;
|
||||||
|
}
|
||||||
|
|
||||||
set infoMapStyle(EntryMapStyle newValue) => setAndNotify(infoMapStyleKey, newValue.toString());
|
set infoMapStyle(EntryMapStyle newValue) => setAndNotify(infoMapStyleKey, newValue.toString());
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ import 'package:aves/services/storage_service.dart';
|
||||||
import 'package:aves/services/window_service.dart';
|
import 'package:aves/services/window_service.dart';
|
||||||
import 'package:aves_report/aves_report.dart';
|
import 'package:aves_report/aves_report.dart';
|
||||||
import 'package:aves_report_platform/aves_report_platform.dart';
|
import 'package:aves_report_platform/aves_report_platform.dart';
|
||||||
|
import 'package:aves_services/aves_services.dart';
|
||||||
|
import 'package:aves_services_platform/aves_services_platform.dart';
|
||||||
import 'package:get_it/get_it.dart';
|
import 'package:get_it/get_it.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ final MediaFileService mediaFileService = getIt<MediaFileService>();
|
||||||
final MediaStoreService mediaStoreService = getIt<MediaStoreService>();
|
final MediaStoreService mediaStoreService = getIt<MediaStoreService>();
|
||||||
final MetadataEditService metadataEditService = getIt<MetadataEditService>();
|
final MetadataEditService metadataEditService = getIt<MetadataEditService>();
|
||||||
final MetadataFetchService metadataFetchService = getIt<MetadataFetchService>();
|
final MetadataFetchService metadataFetchService = getIt<MetadataFetchService>();
|
||||||
|
final MobileServices mobileServices = getIt<MobileServices>();
|
||||||
final ReportService reportService = getIt<ReportService>();
|
final ReportService reportService = getIt<ReportService>();
|
||||||
final StorageService storageService = getIt<StorageService>();
|
final StorageService storageService = getIt<StorageService>();
|
||||||
final WindowService windowService = getIt<WindowService>();
|
final WindowService windowService = getIt<WindowService>();
|
||||||
|
@ -49,6 +52,7 @@ void initPlatformServices() {
|
||||||
getIt.registerLazySingleton<MediaStoreService>(PlatformMediaStoreService.new);
|
getIt.registerLazySingleton<MediaStoreService>(PlatformMediaStoreService.new);
|
||||||
getIt.registerLazySingleton<MetadataEditService>(PlatformMetadataEditService.new);
|
getIt.registerLazySingleton<MetadataEditService>(PlatformMetadataEditService.new);
|
||||||
getIt.registerLazySingleton<MetadataFetchService>(PlatformMetadataFetchService.new);
|
getIt.registerLazySingleton<MetadataFetchService>(PlatformMetadataFetchService.new);
|
||||||
|
getIt.registerLazySingleton<MobileServices>(PlatformMobileServices.new);
|
||||||
getIt.registerLazySingleton<ReportService>(PlatformReportService.new);
|
getIt.registerLazySingleton<ReportService>(PlatformReportService.new);
|
||||||
getIt.registerLazySingleton<StorageService>(PlatformStorageService.new);
|
getIt.registerLazySingleton<StorageService>(PlatformStorageService.new);
|
||||||
getIt.registerLazySingleton<WindowService>(PlatformWindowService.new);
|
getIt.registerLazySingleton<WindowService>(PlatformWindowService.new);
|
||||||
|
|
|
@ -15,7 +15,6 @@ import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||||
import 'package:aves/widgets/common/identity/buttons.dart';
|
import 'package:aves/widgets/common/identity/buttons.dart';
|
||||||
import 'package:aves_services_platform/aves_services_platform.dart';
|
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
@ -145,7 +144,6 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
|
||||||
final packageInfo = await PackageInfo.fromPlatform();
|
final packageInfo = await PackageInfo.fromPlatform();
|
||||||
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||||
final installer = await androidAppService.getAppInstaller();
|
final installer = await androidAppService.getAppInstaller();
|
||||||
final hasMobileServices = await PlatformMobileServices().isServiceAvailable();
|
|
||||||
final flavor = context.read<AppFlavor>().toString().split('.')[1];
|
final flavor = context.read<AppFlavor>().toString().split('.')[1];
|
||||||
return [
|
return [
|
||||||
'Aves version: ${packageInfo.version}-$flavor (Build ${packageInfo.buildNumber})',
|
'Aves version: ${packageInfo.version}-$flavor (Build ${packageInfo.buildNumber})',
|
||||||
|
@ -153,7 +151,7 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
|
||||||
'Android version: ${androidInfo.version.release} (SDK ${androidInfo.version.sdkInt})',
|
'Android version: ${androidInfo.version.release} (SDK ${androidInfo.version.sdkInt})',
|
||||||
'Android build: ${androidInfo.display}',
|
'Android build: ${androidInfo.display}',
|
||||||
'Device: ${androidInfo.manufacturer} ${androidInfo.model}',
|
'Device: ${androidInfo.manufacturer} ${androidInfo.model}',
|
||||||
'Mobile services: ${hasMobileServices ? 'ready' : 'not available'}',
|
'Mobile services: ${mobileServices.isServiceAvailable ? 'ready' : 'not available'}',
|
||||||
'System locales: ${WidgetsBinding.instance.window.locales.join(', ')}',
|
'System locales: ${WidgetsBinding.instance.window.locales.join(', ')}',
|
||||||
'Aves locale: ${settings.locale ?? 'system'} -> ${settings.appliedLocale}',
|
'Aves locale: ${settings.locale ?? 'system'} -> ${settings.appliedLocale}',
|
||||||
'Installer: $installer',
|
'Installer: $installer',
|
||||||
|
|
|
@ -30,7 +30,6 @@ import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/common/providers/highlight_info_provider.dart';
|
import 'package:aves/widgets/common/providers/highlight_info_provider.dart';
|
||||||
import 'package:aves/widgets/home_page.dart';
|
import 'package:aves/widgets/home_page.dart';
|
||||||
import 'package:aves/widgets/welcome_page.dart';
|
import 'package:aves/widgets/welcome_page.dart';
|
||||||
import 'package:aves_services_platform/aves_services_platform.dart';
|
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:fijkplayer/fijkplayer.dart';
|
import 'package:fijkplayer/fijkplayer.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
@ -225,6 +224,7 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
final stopwatch = Stopwatch()..start();
|
final stopwatch = Stopwatch()..start();
|
||||||
|
|
||||||
await device.init();
|
await device.init();
|
||||||
|
await mobileServices.init();
|
||||||
await settings.init(monitorPlatformSettings: true);
|
await settings.init(monitorPlatformSettings: true);
|
||||||
settings.isRotationLocked = await windowService.isRotationLocked();
|
settings.isRotationLocked = await windowService.isRotationLocked();
|
||||||
settings.areAnimationsRemoved = await AccessibilityService.areAnimationsRemoved();
|
settings.areAnimationsRemoved = await AccessibilityService.areAnimationsRemoved();
|
||||||
|
@ -273,14 +273,13 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
|
|
||||||
FlutterError.onError = reportService.recordFlutterError;
|
FlutterError.onError = reportService.recordFlutterError;
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
final hasMobileServices = await PlatformMobileServices().isServiceAvailable();
|
|
||||||
await reportService.setCustomKeys({
|
await reportService.setCustomKeys({
|
||||||
'build_mode': kReleaseMode
|
'build_mode': kReleaseMode
|
||||||
? 'release'
|
? 'release'
|
||||||
: kProfileMode
|
: kProfileMode
|
||||||
? 'profile'
|
? 'profile'
|
||||||
: 'debug',
|
: 'debug',
|
||||||
'has_mobile_services': hasMobileServices,
|
'has_mobile_services': mobileServices.isServiceAvailable,
|
||||||
'locales': WidgetsBinding.instance.window.locales.join(', '),
|
'locales': WidgetsBinding.instance.window.locales.join(', '),
|
||||||
'time_zone': '${now.timeZoneName} (${now.timeZoneOffset})',
|
'time_zone': '${now.timeZoneName} (${now.timeZoneOffset})',
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,6 @@ import 'package:aves/widgets/common/map/buttons/coordinate_filter.dart';
|
||||||
import 'package:aves/widgets/common/map/compass.dart';
|
import 'package:aves/widgets/common/map/compass.dart';
|
||||||
import 'package:aves/widgets/dialogs/aves_selection_dialog.dart';
|
import 'package:aves/widgets/dialogs/aves_selection_dialog.dart';
|
||||||
import 'package:aves_map/aves_map.dart';
|
import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:aves_services_platform/aves_services_platform.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
@ -125,24 +124,15 @@ class MapButtonPanel extends StatelessWidget {
|
||||||
padding: EdgeInsets.only(top: padding),
|
padding: EdgeInsets.only(top: padding),
|
||||||
child: MapOverlayButton(
|
child: MapOverlayButton(
|
||||||
icon: const Icon(AIcons.layers),
|
icon: const Icon(AIcons.layers),
|
||||||
onPressed: () async {
|
onPressed: () => showSelectionDialog<EntryMapStyle>(
|
||||||
final canUseDeviceMaps = await availability.canUseDeviceMaps;
|
context: context,
|
||||||
final availableStyles = [
|
builder: (context) => AvesSelectionDialog<EntryMapStyle>(
|
||||||
if (canUseDeviceMaps) ...PlatformMobileServices().mapStyles,
|
initialValue: settings.infoMapStyle,
|
||||||
...EntryMapStyle.values.where((v) => !v.needDeviceService),
|
options: Map.fromEntries(availability.mapStyles.map((v) => MapEntry(v, v.getName(context)))),
|
||||||
];
|
title: context.l10n.mapStyleTitle,
|
||||||
final preferredStyle = settings.infoMapStyle;
|
),
|
||||||
final initialStyle = availableStyles.contains(preferredStyle) ? preferredStyle : availableStyles.first;
|
onSelection: (v) => settings.infoMapStyle = v,
|
||||||
await showSelectionDialog<EntryMapStyle>(
|
),
|
||||||
context: context,
|
|
||||||
builder: (context) => AvesSelectionDialog<EntryMapStyle>(
|
|
||||||
initialValue: initialStyle,
|
|
||||||
options: Map.fromEntries(availableStyles.map((v) => MapEntry(v, v.getName(context)))),
|
|
||||||
title: context.l10n.mapStyleTitle,
|
|
||||||
),
|
|
||||||
onSelection: (v) => settings.infoMapStyle = v,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
tooltip: context.l10n.mapStyleTooltip,
|
tooltip: context.l10n.mapStyleTooltip,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/entry_images.dart';
|
import 'package:aves/model/entry_images.dart';
|
||||||
import 'package:aves/model/settings/enums/map_style.dart';
|
import 'package:aves/model/settings/enums/map_style.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
import 'package:aves/services/common/services.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/utils/change_notifier.dart';
|
import 'package:aves/utils/change_notifier.dart';
|
||||||
import 'package:aves/utils/constants.dart';
|
import 'package:aves/utils/constants.dart';
|
||||||
|
@ -15,7 +16,6 @@ import 'package:aves/widgets/common/map/decorator.dart';
|
||||||
import 'package:aves/widgets/common/map/leaflet/map.dart';
|
import 'package:aves/widgets/common/map/leaflet/map.dart';
|
||||||
import 'package:aves/widgets/common/thumbnail/image.dart';
|
import 'package:aves/widgets/common/thumbnail/image.dart';
|
||||||
import 'package:aves_map/aves_map.dart';
|
import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:aves_services_platform/aves_services_platform.dart';
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:fluster/fluster.dart';
|
import 'package:fluster/fluster.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -71,8 +71,6 @@ class _GeoMapState extends State<GeoMap> {
|
||||||
|
|
||||||
List<AvesEntry> get entries => widget.entries;
|
List<AvesEntry> get entries => widget.entries;
|
||||||
|
|
||||||
static final _platformMobileServices = PlatformMobileServices();
|
|
||||||
|
|
||||||
// cap initial zoom to avoid a zoom change
|
// cap initial zoom to avoid a zoom change
|
||||||
// when toggling overlay on Google map initial state
|
// when toggling overlay on Google map initial state
|
||||||
static const double minInitialZoom = 3;
|
static const double minInitialZoom = 3;
|
||||||
|
@ -172,7 +170,7 @@ class _GeoMapState extends State<GeoMap> {
|
||||||
case EntryMapStyle.googleTerrain:
|
case EntryMapStyle.googleTerrain:
|
||||||
case EntryMapStyle.hmsNormal:
|
case EntryMapStyle.hmsNormal:
|
||||||
case EntryMapStyle.hmsTerrain:
|
case EntryMapStyle.hmsTerrain:
|
||||||
child = _platformMobileServices.buildMap<AvesEntry>(
|
child = mobileServices.buildMap<AvesEntry>(
|
||||||
controller: widget.controller,
|
controller: widget.controller,
|
||||||
clusterListenable: _clusterChangeNotifier,
|
clusterListenable: _clusterChangeNotifier,
|
||||||
boundsNotifier: _boundsNotifier,
|
boundsNotifier: _boundsNotifier,
|
||||||
|
|
|
@ -5,7 +5,9 @@ import 'package:flutter/widgets.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
abstract class MobileServices {
|
abstract class MobileServices {
|
||||||
Future<bool> isServiceAvailable();
|
Future<void> init();
|
||||||
|
|
||||||
|
bool get isServiceAvailable;
|
||||||
|
|
||||||
EntryMapStyle get defaultMapStyle;
|
EntryMapStyle get defaultMapStyle;
|
||||||
|
|
||||||
|
|
|
@ -3,28 +3,43 @@ library aves_services_platform;
|
||||||
import 'package:aves_map/aves_map.dart';
|
import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:aves_services/aves_services.dart';
|
import 'package:aves_services/aves_services.dart';
|
||||||
import 'package:aves_services_platform/src/map.dart';
|
import 'package:aves_services_platform/src/map.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:google_api_availability/google_api_availability.dart';
|
import 'package:google_api_availability/google_api_availability.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
class PlatformMobileServices extends MobileServices {
|
class PlatformMobileServices extends MobileServices {
|
||||||
bool? _isAvailable;
|
bool _isAvailable = false;
|
||||||
|
bool _canRenderMaps = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isServiceAvailable() async {
|
Future<void> init() async {
|
||||||
if (_isAvailable != null) return SynchronousFuture(_isAvailable!);
|
|
||||||
final result = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability();
|
final result = await GoogleApiAvailability.instance.checkGooglePlayServicesAvailability();
|
||||||
_isAvailable = result == GooglePlayServicesAvailability.success;
|
_isAvailable = result == GooglePlayServicesAvailability.success;
|
||||||
debugPrint('Device has Google Play Services=$_isAvailable');
|
debugPrint('Device has Google Play Services=$_isAvailable');
|
||||||
return _isAvailable!;
|
|
||||||
|
// 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 API 19 too,
|
||||||
|
// cf https://github.com/flutter/flutter/issues/23728
|
||||||
|
// as of google_maps_flutter v2.1.5, Flutter v3.0.1 makes the map hide overlay widgets on API <=22
|
||||||
|
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||||
|
_canRenderMaps = (androidInfo.version.sdkInt ?? 0) >= 23;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isServiceAvailable => _isAvailable;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
EntryMapStyle get defaultMapStyle => EntryMapStyle.googleNormal;
|
EntryMapStyle get defaultMapStyle => EntryMapStyle.googleNormal;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<EntryMapStyle> get mapStyles => [EntryMapStyle.googleNormal, EntryMapStyle.googleHybrid, EntryMapStyle.googleTerrain];
|
List<EntryMapStyle> get mapStyles => (isServiceAvailable && _canRenderMaps)
|
||||||
|
? [
|
||||||
|
EntryMapStyle.googleNormal,
|
||||||
|
EntryMapStyle.googleHybrid,
|
||||||
|
EntryMapStyle.googleTerrain,
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildMap<T>({
|
Widget buildMap<T>({
|
||||||
|
|
|
@ -12,6 +12,7 @@ dependencies:
|
||||||
path: ../aves_map
|
path: ../aves_map
|
||||||
aves_services:
|
aves_services:
|
||||||
path: ../aves_services
|
path: ../aves_services
|
||||||
|
device_info_plus:
|
||||||
google_api_availability:
|
google_api_availability:
|
||||||
google_maps_flutter:
|
google_maps_flutter:
|
||||||
latlong2:
|
latlong2:
|
||||||
|
|
|
@ -3,7 +3,6 @@ library aves_services_platform;
|
||||||
import 'package:aves_map/aves_map.dart';
|
import 'package:aves_map/aves_map.dart';
|
||||||
import 'package:aves_services/aves_services.dart';
|
import 'package:aves_services/aves_services.dart';
|
||||||
import 'package:aves_services_platform/src/map.dart';
|
import 'package:aves_services_platform/src/map.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
|
import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
|
@ -12,22 +11,28 @@ class PlatformMobileServices extends MobileServices {
|
||||||
// cf https://developer.huawei.com/consumer/en/doc/development/hmscore-common-References/huaweiapiavailability-0000001050121134#section9492524178
|
// cf https://developer.huawei.com/consumer/en/doc/development/hmscore-common-References/huaweiapiavailability-0000001050121134#section9492524178
|
||||||
static const int _hmsCoreAvailable = 0;
|
static const int _hmsCoreAvailable = 0;
|
||||||
|
|
||||||
bool? _isAvailable;
|
bool _isAvailable = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> isServiceAvailable() async {
|
Future<void> init() async {
|
||||||
if (_isAvailable != null) return SynchronousFuture(_isAvailable!);
|
|
||||||
final result = await HmsApiAvailability().isHMSAvailable();
|
final result = await HmsApiAvailability().isHMSAvailable();
|
||||||
_isAvailable = result == _hmsCoreAvailable;
|
_isAvailable = result == _hmsCoreAvailable;
|
||||||
debugPrint('Device has Huawei Mobile Services=$_isAvailable');
|
debugPrint('Device has Huawei Mobile Services=$_isAvailable');
|
||||||
return _isAvailable!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isServiceAvailable => _isAvailable;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
EntryMapStyle get defaultMapStyle => EntryMapStyle.hmsNormal;
|
EntryMapStyle get defaultMapStyle => EntryMapStyle.hmsNormal;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<EntryMapStyle> get mapStyles => [EntryMapStyle.hmsNormal, EntryMapStyle.hmsTerrain];
|
List<EntryMapStyle> get mapStyles => isServiceAvailable
|
||||||
|
? [
|
||||||
|
EntryMapStyle.hmsNormal,
|
||||||
|
EntryMapStyle.hmsTerrain,
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildMap<T>({
|
Widget buildMap<T>({
|
||||||
|
|
Loading…
Reference in a new issue