31a844bb94
Without a light sensor an app may read (the Redmi Pad SE has none), auto is dark while the sun is more than 4° below the horizon (lib/theme/sun.dart), at Android's coarse location, polled and kept across restarts. The tablet's own, not the Orin's GNSS: the tablet has its own GNSS and cellular. Android's dark theme is the last fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
49 lines
2.0 KiB
Dart
49 lines
2.0 KiB
Dart
// Auto dark/bright from the sun: dark once it is far enough below the horizon, at the
|
|
// tablet's own rough location (Android's, not the Orin's: the tablet stands on its own).
|
|
// Google Maps on this tablet does the same (it reads no light sensor; checked). Needs no
|
|
// sensor; does not know about tunnels or car parks.
|
|
|
|
import 'dart:math' as math;
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
/// The tablet's newest known location, roughly, from MainActivity; null without one
|
|
/// (or before location is granted: the first call asks).
|
|
Future<(double, double)?> androidLocation() async {
|
|
try {
|
|
final v = await const MethodChannel('yukart/location')
|
|
.invokeListMethod<double>('last');
|
|
return v == null || v.length < 2 ? null : (v[0], v[1]);
|
|
} catch (_) {
|
|
return null; // No Android side (tests, desktop).
|
|
}
|
|
}
|
|
|
|
/// Dark while the sun is lower than this (degrees; sunset is -0.8, civil dusk -6).
|
|
const darkBelowDeg = -4.0;
|
|
|
|
/// The sun's elevation above the horizon, in degrees, at [lat], [lon] (degrees, east
|
|
/// positive) and [time]. The usual low-precision formulae (the Astronomical Almanac's,
|
|
/// as NOAA uses them): within about a degree, plenty for this.
|
|
double sunElevation(double lat, double lon, DateTime time) {
|
|
double rad(double d) => d * math.pi / 180;
|
|
double deg(double r) => r * 180 / math.pi;
|
|
final d =
|
|
time.toUtc().millisecondsSinceEpoch / 86400000 + 2440587.5 - 2451545.0;
|
|
final g = rad(357.529 + 0.98560028 * d); // mean anomaly
|
|
final q = 280.459 + 0.98564736 * d; // mean longitude
|
|
final l = rad(q + 1.915 * math.sin(g) + 0.020 * math.sin(2 * g));
|
|
final e = rad(23.439 - 0.00000036 * d); // obliquity
|
|
final ra = math.atan2(math.cos(e) * math.sin(l), math.cos(l));
|
|
final dec = math.asin(math.sin(e) * math.sin(l));
|
|
final gmst = (18.697374558 + 24.06570982441908 * d) % 24;
|
|
final ha = rad(gmst * 15 + lon) - ra;
|
|
final phi = rad(lat);
|
|
return deg(
|
|
math.asin(
|
|
math.sin(phi) * math.sin(dec) +
|
|
math.cos(phi) * math.cos(dec) * math.cos(ha),
|
|
),
|
|
);
|
|
}
|