mirror of
https://github.com/PranshulGG/WeatherMaster.git
synced 2026-10-22 02:52:37 -05:00
updated v2.6.1
This commit is contained in:
1 parent
abd5b88af2
commit
ed64ba0779
17 files changed
+103
-72
No files matched your search
@@ -10,24 +10,26 @@ import android.location.LocationManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import androidx.core.app.ActivityCompat
|
||||
|
||||
class LocationHelper(private val activity: Activity) {
|
||||
|
||||
private val locationManager =
|
||||
activity.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
// Talks to GPS & network
|
||||
|
||||
private var pendingCallback: LocationResult? = null
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private var listener: LocationListener? = null
|
||||
|
||||
companion object {
|
||||
private const val LOCATION_REQUEST_CODE = 999
|
||||
private const val TIMEOUT_MS = 10_000L // Max wait 10 seconds
|
||||
private const val TIMEOUT_MS = 60_000L // 60 seconds for slower fixes
|
||||
}
|
||||
|
||||
// Public method to get location
|
||||
fun getCurrentPosition(callback: LocationResult) {
|
||||
pendingCallback = callback
|
||||
|
||||
// Step 0: Permission check
|
||||
if (ActivityCompat.checkSelfPermission(
|
||||
activity,
|
||||
@@ -38,25 +40,45 @@ class LocationHelper(private val activity: Activity) {
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
) {
|
||||
// Request permission if missing
|
||||
ActivityCompat.requestPermissions(
|
||||
activity,
|
||||
arrayOf(
|
||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
||||
),
|
||||
LOCATION_REQUEST_CODE
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Step 1: Try last known location first (fastest route)
|
||||
// Step 1: Try last known location first
|
||||
val lastLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
|
||||
?: locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
|
||||
?: locationManager.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER)
|
||||
|
||||
if (lastLocation != null) {
|
||||
callback.onSuccess(lastLocation.latitude, lastLocation.longitude)
|
||||
return
|
||||
}
|
||||
|
||||
// Step 2: Set up listener for updates
|
||||
pendingCallback = callback
|
||||
val listener = object : LocationListener {
|
||||
// Step 2: Check available providers
|
||||
val providers = mutableListOf<String>()
|
||||
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) providers.add(LocationManager.GPS_PROVIDER)
|
||||
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) providers.add(LocationManager.NETWORK_PROVIDER)
|
||||
if (locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)) providers.add(LocationManager.PASSIVE_PROVIDER)
|
||||
|
||||
if (providers.isEmpty()) {
|
||||
callback.onFailure("No location provider enabled")
|
||||
return
|
||||
}
|
||||
|
||||
// Step 3: Set up listener
|
||||
listener = object : LocationListener {
|
||||
override fun onLocationChanged(location: Location) {
|
||||
// Pass it on
|
||||
Log.d("LocationHelper", "Location received: ${location.latitude}, ${location.longitude}")
|
||||
pendingCallback?.onSuccess(location.latitude, location.longitude)
|
||||
removeUpdates(this)
|
||||
removeUpdates()
|
||||
}
|
||||
|
||||
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}
|
||||
@@ -64,33 +86,32 @@ class LocationHelper(private val activity: Activity) {
|
||||
override fun onProviderDisabled(provider: String) {}
|
||||
}
|
||||
|
||||
// Ask GPS and Network (network usually faster indoors)
|
||||
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
|
||||
locationManager.requestLocationUpdates(
|
||||
LocationManager.GPS_PROVIDER,
|
||||
0L,
|
||||
0f,
|
||||
listener
|
||||
)
|
||||
}
|
||||
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
|
||||
locationManager.requestLocationUpdates(
|
||||
LocationManager.NETWORK_PROVIDER,
|
||||
0L,
|
||||
0f,
|
||||
listener
|
||||
)
|
||||
// Request updates from all available providers
|
||||
providers.forEach { provider ->
|
||||
try {
|
||||
locationManager.requestLocationUpdates(
|
||||
provider,
|
||||
1000L, // 1-second interval
|
||||
0f,
|
||||
listener!!
|
||||
)
|
||||
} catch (e: SecurityException) {
|
||||
Log.e("LocationHelper", "Permission issue: $e")
|
||||
} catch (e: Exception) {
|
||||
Log.e("LocationHelper", "Failed to request updates for $provider: $e")
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Timeout in case nothing arrives
|
||||
// Step 4: Timeout handler
|
||||
handler.postDelayed({
|
||||
pendingCallback?.onFailure("Location timeout")
|
||||
removeUpdates(listener)
|
||||
removeUpdates()
|
||||
}, TIMEOUT_MS)
|
||||
}
|
||||
|
||||
private fun removeUpdates(listener: LocationListener) {
|
||||
locationManager.removeUpdates(listener)
|
||||
private fun removeUpdates() {
|
||||
listener?.let { locationManager.removeUpdates(it) }
|
||||
listener = null
|
||||
pendingCallback = null
|
||||
}
|
||||
|
||||
@@ -99,12 +120,9 @@ class LocationHelper(private val activity: Activity) {
|
||||
if (requestCode == LOCATION_REQUEST_CODE) {
|
||||
val callback = pendingCallback
|
||||
pendingCallback = null
|
||||
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
// User said yes → fetch location
|
||||
callback?.let { getCurrentPosition(it) }
|
||||
} else {
|
||||
// User said no → sad face
|
||||
callback?.onFailure("Location permission denied")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ String getDayLabel(DateTime date, int index, utcOffsetSeconds) {
|
||||
}
|
||||
}
|
||||
|
||||
final String currentVersion = 'v2.6.0';
|
||||
final String currentVersion = 'v2.6.1';
|
||||
final String githubRepo = 'PranshulGG/WeatherMaster';
|
||||
bool isChecking = false;
|
||||
|
||||
|
||||
@@ -419,10 +419,18 @@ class _ShowInsightsState extends State<ShowInsights> {
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
margin: const EdgeInsets.fromLTRB(12, 0, 12, 0),
|
||||
margin: const EdgeInsets.fromLTRB(13, 0, 13, 0),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(widget.selectedContainerBgIndex),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withValues(alpha: 0.15),
|
||||
spreadRadius: 1,
|
||||
blurRadius: 1,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
constraints: BoxConstraints(minHeight: 65),
|
||||
child: IntrinsicHeight(
|
||||
|
||||
@@ -108,7 +108,7 @@ class AboutPage extends StatelessWidget {
|
||||
showLicensePage(
|
||||
context: context,
|
||||
applicationName: 'WeatherMaster',
|
||||
applicationVersion: 'v2.6.0 (F)',
|
||||
applicationVersion: 'v2.6.1 (F)',
|
||||
applicationIcon: Container(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
margin: EdgeInsets.only(bottom: 16, top: 16),
|
||||
@@ -353,7 +353,7 @@ class CheckUpdateButton extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _CheckUpdateButtonState extends State<CheckUpdateButton> {
|
||||
final String currentVersion = 'v2.6.0';
|
||||
final String currentVersion = 'v2.6.1';
|
||||
final String githubRepo = 'PranshulGG/WeatherMaster';
|
||||
bool isChecking = false;
|
||||
|
||||
|
||||
@@ -1458,7 +1458,7 @@ class _WeatherHomeState extends State<WeatherHome> {
|
||||
currentLastUpdated: formattedTime,
|
||||
),
|
||||
WeatherFrogIconWidget(iconUrl: _iconUrlFroggy),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: 13.8),
|
||||
SizedBox(
|
||||
width: isFoldableLayout(context) ? 500 : null,
|
||||
height: null,
|
||||
|
||||
@@ -285,7 +285,8 @@ Future<void> updateHomeWidget(weather, {bool updatedFromHome = false}) async {
|
||||
await HomeWidget.updateWidget(
|
||||
name: 'WeatherWidgetCastProvider', iOSName: null);
|
||||
await HomeWidget.updateWidget(name: 'PillWidgetProvider', iOSName: null);
|
||||
await HomeWidget.updateWidget(name: 'GlanceWidgetProvider', iOSName: null);
|
||||
await HomeWidget.updateWidget(
|
||||
name: 'clockDateWidgetProvider', iOSName: null);
|
||||
await HomeWidget.updateWidget(
|
||||
name: 'DateCurrentWidgetProvider', iOSName: null);
|
||||
|
||||
|
||||
@@ -73,13 +73,11 @@ class ConditionsWidgets extends StatefulWidget {
|
||||
class _ConditionsWidgetsState extends State<ConditionsWidgets> {
|
||||
List<int> itemOrder = [];
|
||||
|
||||
final String orderPrefsKey = 'tile_order';
|
||||
bool _initialized = false;
|
||||
final String orderPrefsKey = 'tile_order_new';
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadTileOrder();
|
||||
_initializePreferences();
|
||||
}
|
||||
|
||||
Future<void> _loadTileOrder() async {
|
||||
@@ -97,28 +95,6 @@ class _ConditionsWidgetsState extends State<ConditionsWidgets> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _initializePreferences() async {
|
||||
if (_initialized) return;
|
||||
_initialized = true;
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
List<String>? savedList = prefs.getStringList(orderPrefsKey);
|
||||
|
||||
if (savedList != null) {
|
||||
List<int> intList = savedList.map(int.parse).toList();
|
||||
List<int> zeroToSeven = List.generate(8, (i) => i);
|
||||
|
||||
if (intList.toSet().containsAll(zeroToSeven) &&
|
||||
intList.every((e) => e >= 0 && e <= 7)) {
|
||||
await prefs.remove(orderPrefsKey);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> newList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
await prefs.setStringList(orderPrefsKey, newList);
|
||||
print('New list saved');
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final tempUnit = context.watch<UnitSettingsNotifier>().tempUnit;
|
||||
@@ -756,7 +732,7 @@ class _ConditionsWidgetsState extends State<ConditionsWidgets> {
|
||||
backgroundColor:
|
||||
Color(widget.selectedContainerBgIndex)),
|
||||
headerWidgetConditions(
|
||||
headerText: "direction".tr(),
|
||||
headerText: "wind".tr(),
|
||||
headerIcon: Symbols.explore,
|
||||
),
|
||||
Align(
|
||||
@@ -1297,7 +1273,11 @@ class _ConditionsWidgetsState extends State<ConditionsWidgets> {
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
widget.isFromHome ? openContainer() : null;
|
||||
if (widget.isFromHome) {
|
||||
if (moonriseFormat != "N/A" && moonsetFormat != "N/A") {
|
||||
openContainer();
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -1386,7 +1366,7 @@ class _ConditionsWidgetsState extends State<ConditionsWidgets> {
|
||||
// 123216
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.fromLTRB(12, 0, 12, 0),
|
||||
margin: EdgeInsets.fromLTRB(13, 0, 13, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
|
||||
@@ -77,7 +77,7 @@ class DailyCard extends StatelessWidget {
|
||||
top: 15,
|
||||
bottom: 0,
|
||||
),
|
||||
margin: EdgeInsets.fromLTRB(12, 0, 12, 0),
|
||||
margin: EdgeInsets.fromLTRB(13, 0, 13, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
|
||||
@@ -65,7 +65,7 @@ class HourlyCard extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.only(top: 15, bottom: 0),
|
||||
margin: EdgeInsets.fromLTRB(12, 0, 12, 0),
|
||||
margin: EdgeInsets.fromLTRB(13, 0, 13, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
|
||||
@@ -99,7 +99,7 @@ class PollenCard extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
margin: EdgeInsets.fromLTRB(12, 0, 12, 0),
|
||||
margin: EdgeInsets.fromLTRB(13, 0, 13, 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
|
||||
|
||||
@@ -177,7 +177,7 @@ class RainBlock extends StatelessWidget {
|
||||
final precipitationUnit = unitSettings.precipitationUnit;
|
||||
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(bottom: 0, left: 12, right: 12, top: 0),
|
||||
margin: const EdgeInsets.only(bottom: 0, left: 13, right: 13, top: 0),
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(selectedContainerBgIndex),
|
||||
|
||||
@@ -568,7 +568,7 @@ class _SummaryCardState extends State<SummaryCard> {
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.only(top: 15, bottom: 10),
|
||||
margin: EdgeInsets.fromLTRB(12, 0, 12, 0),
|
||||
margin: EdgeInsets.fromLTRB(13, 0, 13, 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 2.6.0+21
|
||||
version: 2.6.1+22
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.6 <4.0.0"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+24
@@ -622,3 +622,27 @@ create_cxx_tasks
|
||||
[gap of 32ms]
|
||||
create_cxx_tasks completed in 251ms
|
||||
|
||||
# C/C++ build system timings
|
||||
create_cxx_tasks
|
||||
create-initial-cxx-model
|
||||
create-module-model 121ms
|
||||
[gap of 15ms]
|
||||
create-variant-model 28ms
|
||||
create-ARMEABI_V7A-model 85ms
|
||||
create-ARM64_V8A-model 11ms
|
||||
create-X86-model 11ms
|
||||
create-X86_64-model 11ms
|
||||
create-module-model 16ms
|
||||
create-ARMEABI_V7A-model 17ms
|
||||
create-ARM64_V8A-model 17ms
|
||||
create-X86-model 19ms
|
||||
create-X86_64-model 17ms
|
||||
create-module-model 24ms
|
||||
create-ARMEABI_V7A-model 14ms
|
||||
create-ARM64_V8A-model 18ms
|
||||
create-X86-model 23ms
|
||||
create-X86_64-model 11ms
|
||||
create-initial-cxx-model completed in 490ms
|
||||
[gap of 49ms]
|
||||
create_cxx_tasks completed in 560ms
|
||||
|
||||
Reference in new issue
Block a user