Improve location service reliability with backup timer
這是什麼類型的 PR?
選擇所有符合的項目
- [ ] 重構
- [ ] 新功能
- [x] 錯誤修復
- [ ] 最佳化
- [ ] 技術文件更新
描述
使用前景服務顯示通知
相關 issue
- 相關問題 #
- closes #
QA 指南、截圖、錄像
請將這行替換成:如何測試您的 PR 的步驟,已測試的裝置註釋,以及任何相關的 UI 更改圖片。
UI 無障礙清單
如果您的 PR 包含 UI 更改,請使用此清單:
- [ ] 變數名稱實現語意化命名?
- [ ] 測試通過 AA 顏色對比?
@claude review
Claude finished @bamboo0403's task —— View job
Code Review Progress
- [x] Read repository guidelines (CLAUDE.md)
- [x] Review changed files
- [x] Check AndroidManifest.xml for service declaration
- [x] Analyze PR diff changes
- [x] Provide comprehensive feedback
Code Review
I've reviewed this PR which refactors the auto location notification system. Here are my findings:
✅ Good News: Previous Critical Issue Resolved
The critical issue from the previous review has been resolved! I can confirm:
- The
LocationForegroundServicedeclaration has been removed from AndroidManifest.xml - The app no longer attempts to use a non-existent service class
- No runtime crashes will occur from missing service implementation
📊 Summary of Changes
This PR primarily consists of code formatting and cleanup:
-
Build Version: Bumped from
300103027to300103035(android/app/build.gradle:52) - Documentation: Updated class comment to "Background location service with foreground support"
- Code Cleanup: Removed extensive inline documentation comments
- Formatting: Improved line breaks for better readability
- Whitespace: Removed unnecessary blank lines throughout
🔍 Analysis
Positive Changes:
- ✅ Code is more concise and follows consistent formatting
- ✅ Better line breaking for long conditional statements (lines 45-46, 175-176, 274-275, 297-302, 309-315, 319-325)
- ✅ Removed excessive whitespace that made the code harder to scan
- ✅ The notification system uses
NotificationCategory.Serviceappropriately (line 251) - ✅ Chinese comments added to mark foreground notification sections (lines 193, 229, 332)
Concerns:
-
⚠️ Documentation Removal (lines 20-37 in diff)
- Removed helpful inline documentation comments like:
- "The alarm ID used for periodic location updates"
- "The notification ID used for location updates notification"
- "Platform channel for iOS"
- "Whether the background service is available on the current platform"
- While this reduces line count, it makes the code less self-documenting for future maintainers
- Impact: Medium - May make onboarding new developers more difficult
- Removed helpful inline documentation comments like:
-
⚠️ Missing Newline at EOF (line 408)
- The file now ends without a newline character after the closing brace
- This violates common code style conventions and may cause issues with some tools
- Impact: Low - Easy fix, cosmetic issue
-
❓ PR Description Missing
- No description explaining what bug this fixes
- No explanation of how "foreground service" is actually being used
- Title mentions "ForegroundService" but the manifest has no service declaration
-
What changed: The code uses
NotificationCategory.Servicebut relies on AlarmManager, not an actual Android ForegroundService
🤔 Clarification Needed
The PR title says "Use ForegroundService to show auto location notify" but:
- There is no actual Android
ServiceorForegroundServiceclass implementation - The code uses
NotificationCategory.ServicewithAwesomeNotifications - Background work is still handled by
AlarmManager+ background isolates
Is this intentional? If so, consider updating the PR title to be more accurate, such as:
- "Show service notification during auto location updates"
- "Add foreground notification for background location tracking"
📝 Recommendations
Must Fix:
- [ ] Add newline at end of
lib/core/service.dart:408
Should Consider:
- [ ] Update PR description explaining what this fixes and how it was tested
- [ ] Consider whether removing all inline documentation improves or harms maintainability
- [ ] Update PR title if the change doesn't actually involve Android ForegroundService implementation
Minor:
- The Chinese comments (// --- 前景通知開始 --- ) are helpful for structure but ensure all team members understand them
🎯 Verdict
This PR is mostly good - it's primarily a refactoring/cleanup PR with no functional bugs detected. The previous critical issue has been resolved. The main concerns are around documentation removal and the potentially misleading PR title.
Recommendation: ✅ Approve with minor fixes (add EOF newline, update description)
@claude review
Claude finished @bamboo0403's task —— View job
Code Review Progress
- [x] Read repository guidelines (CLAUDE.md)
- [x] Review changed files
- [x] Check new LocationForegroundService.kt implementation
- [x] Verify AndroidManifest.xml service declaration
- [x] Analyze MainActivity.kt integration
- [x] Review service.dart changes
- [x] Compare with previous review feedback
- [x] Provide comprehensive review feedback
Code Review
I've reviewed this PR which implements a proper Android foreground service for location tracking. This is a significant improvement over the previous version!
✅ Excellent News: Critical Issues Resolved!
The critical issue from the previous review has been completely fixed:
- ✅ The
LocationForegroundServiceclass is now properly implemented (LocationForegroundService.kt) - ✅ The service is correctly declared in AndroidManifest.xml with proper permissions
- ✅ The service is properly integrated with Flutter through MethodChannel in MainActivity.kt
- ✅ The Dart code now starts/stops the foreground service at appropriate times
This is now a real Android ForegroundService implementation, not just a notification category change!
📊 Summary of Changes
1. New File: LocationForegroundService.kt ✅
A proper Android foreground service implementation with:
- Minimal importance notification channel (IMPORTANCE_MIN)
- Persistent foreground notification (ID: 888999)
- START_STICKY restart behavior
- Proper notification with Chinese text "正在更新定位…"
2. AndroidManifest.xml ✅
- Proper service declaration with
foregroundServiceType="location" - Required permissions:
FOREGROUND_SERVICEandFOREGROUND_SERVICE_LOCATION - Service correctly configured as non-exported
3. MainActivity.kt ✅
- New MethodChannel:
com.exptech.dpip/location - Methods to start/stop the foreground service from Dart
- Proper use of
startForegroundService()API
4. service.dart ✅
- Integration with the native foreground service via platform channel
- Service starts when location tracking begins (line 82)
- Service stops when location tracking stops (line 135, 199, 227, 233)
- Notification ID matches the native service (kNotificationId = 888999)
5. build.gradle ✅
- Version bump:
300103035→300103036
🔍 Detailed Analysis
✅ What's Working Well
-
Proper Foreground Service Lifecycle (service.dart)
- Service starts before scheduling the alarm (line 82)
- Service stops when auto-location is disabled (line 135)
- Service stops after location update completes (line 227)
- Service stops on error (line 233)
- Clean lifecycle management prevents service leaks
-
Notification Channel Configuration (LocationForegroundService.kt:39-49)
- Uses
IMPORTANCE_MINfor minimal user disruption - Proper channel creation for Android O+
- Matches the notification ID between Dart and Kotlin (888999)
- Uses
-
Service Configuration (AndroidManifest.xml:59-63)
- Correct
foregroundServiceType="location" - Properly marked as
android:exported="false" - All required permissions declared
- Correct
-
Platform Channel Integration (MainActivity.kt:14-32)
- Clean method channel implementation
- Proper error handling with
result.success()andresult.notImplemented() - Correct use of Android's
startForegroundService()API
-
Code Cleanup (service.dart)
- Removed excessive inline documentation
- Better line breaks for readability
- More concise code structure
⚠️ Issues & Recommendations
Critical Issues: None! 🎉
High Priority Issues
-
⚠️ Missing EOF Newline (service.dart:371)
- File ends without a newline character
- Violates coding standards and may cause git issues
- Fix: Add a newline at the end of the file
-
⚠️ Potential Service Leak on Alarm Failure (service.dart:92-107)
- If the first
AndroidAlarmManager.oneShot()fails and falls back to inexact alarm - The foreground service started at line 82 might not stop if the fallback also fails
- Impact: Service could remain running indefinitely
- Recommendation: Add a try-catch around line 82 or ensure service stops on failure
try { await platform.invokeMethod('startForegroundService'); // alarm scheduling code } catch (e, s) { await platform.invokeMethod('stopForegroundService'); // Clean up rethrow; } - If the first
Medium Priority Issues
-
⚠️ Duplicate Service Start (service.dart:82 and 191)
- The foreground service is started in
start()at line 82 - Then started again in
_$task()at line 191 - This is redundant on the first run
-
Impact: Minor - multiple
startForegroundService()calls are idempotent -
Recommendation: Consider removing line 191 since service already starts in
start() -
However: If alarms trigger
_$task()directly (after reboot), line 191 might be necessary - Verify if
rescheduleOnReboot: trueproperly callsstart()or directly calls_$task()
- The foreground service is started in
-
⚠️ Service Priority PRIORITY_MIN (LocationForegroundService.kt:27)
- Using
PRIORITY_MINon the notification - This is good for user experience but might get killed by aggressive battery optimization
-
Consideration: If users report location updates stopping, consider using
PRIORITY_LOWinstead - Current choice seems reasonable for background location tracking
- Using
Low Priority Issues
-
ℹ️ Hardcoded Chinese Text (LocationForegroundService.kt:24)
- "正在更新定位…" is hardcoded in Kotlin
- Should ideally use Android string resources for i18n
-
Recommendation: Create
res/values/strings.xmlandres/values-zh-rTW/strings.xml
<string name="location_updating">Updating location…</string> <string name="location_updating">正在更新定位…</string>Then use:
.setContentText(getString(R.string.location_updating)) -
ℹ️ Service Never Calls stopSelf() (LocationForegroundService.kt)
- The service starts but never stops itself
- Relies entirely on external
stopService()calls - This is acceptable for this use case, but worth noting
- Current implementation is correct for a service controlled by the app
-
ℹ️ No Pending Intent in Notification (LocationForegroundService.kt:22-28)
- Notification has no
setContentIntent() - Tapping notification does nothing
- Recommendation: Add a PendingIntent to open the app
val intent = Intent(this, MainActivity::class.java) val pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_IMMUTABLE ) .setContentIntent(pendingIntent) - Notification has no
-
ℹ️ Inconsistent Comment Language (service.dart)
- Mix of English and Chinese comments
- Lines 24, 81, 134, 190, 226 have Chinese comments
- Rest of codebase uses English
- Minor: Ensure team is comfortable with mixed language comments
🎯 Comparison with Previous Review
The previous review (from the comments) noted:
- ❌ "There is no actual Android Service or ForegroundService class implementation"
- ❌ "The code uses NotificationCategory.Service with AwesomeNotifications"
- ❌ "No actual Android ForegroundService implementation"
This PR completely addresses those concerns:
- ✅ Real
LocationForegroundServiceclass extending AndroidService - ✅ Proper
startForeground()call inonCreate() - ✅ Service properly declared in manifest
- ✅ Integration with Flutter through MethodChannel
The previous review's title concern is now resolved - this PR does exactly what the title says!
📝 Testing Recommendations
Please verify the following scenarios:
Functional Testing:
- [ ] Location updates work correctly with foreground service
- [ ] Notification appears when service starts
- [ ] Notification disappears when service stops
- [ ] Service properly handles app being killed
- [ ] Service restarts after device reboot (if auto-location enabled)
- [ ] Watch displays notifications correctly (mentioned in PR description)
Edge Cases:
- [ ] What happens if user swipes away the notification? (should not stop service)
- [ ] Service behavior when battery optimization is aggressive
- [ ] Service stops properly when user disables auto-location
- [ ] Multiple rapid start/stop calls don't cause issues
Permissions:
- [ ] Test on Android 14+ with new location permission requirements
- [ ] Verify
FOREGROUND_SERVICE_LOCATIONpermission is properly requested
🎯 Final Verdict
This PR is significantly improved and implements a proper foreground service as the title indicates!
Strengths:
- ✅ Proper Android ForegroundService implementation
- ✅ Correct lifecycle management
- ✅ Clean integration with Flutter
- ✅ All required permissions and manifest entries
- ✅ Previous critical issues completely resolved
Required Fixes:
- [ ] Add newline at end of service.dart:371
Recommended Improvements:
- [ ] Add try-catch around foreground service start to prevent service leak on alarm failure
- [ ] Consider internationalization for notification text
- [ ] Consider adding PendingIntent to notification for better UX
Recommendation: ✅ Approve after adding EOF newline
The critical functionality is solid. The required fix is trivial. The recommended improvements are enhancements that can be addressed in future PRs if needed.
Great work addressing the previous review feedback! This is now a proper foreground service implementation. 👏
--- | | Branch: fix/auto-location
我覺得定位死掉還有一種可能,就是 task 意外死掉,或是被系統提前殺死,導致下一個週期沒辦法建立,可以試試看建立一個更長的週期(1小時)當成備用。
Claude finished @lowrt's task —— View job
Code Review Progress
- [x] Read repository guidelines (CLAUDE.md)
- [x] Review current implementation
- [x] Check if previous review issues were addressed
- [x] Analyze whes1015's backup timer suggestion
- [x] Provide comprehensive feedback
Code Review
I've reviewed the latest changes to this PR. Here's my comprehensive analysis:
🎯 Summary
This PR has undergone several iterations and is now significantly improved. The latest commits have made important fixes to address issues identified in previous reviews, particularly around alarm scheduling robustness.
✅ What's Working Well
1. Critical Bug Fixed: Duplicate Alarm Scheduling (service.dart:82-137)
The previous review noted duplicate AndroidAlarmManager.oneShot() calls at lines 82 and 114. This has been fixed!
- The new code at lines 82-112 properly wraps the foreground service start and alarm scheduling together
- Proper error handling with fallback to inexact alarm if exact alarm fails
- Service cleanup on failure (line 105)
2. Proper Foreground Service Implementation
All components are correctly implemented:
- ✅ LocationForegroundService.kt: Clean, minimal service with IMPORTANCE_MIN notification
- ✅ MainActivity.kt: Proper MethodChannel integration for start/stop
- ✅ AndroidManifest.xml: Correct service declaration with
foregroundServiceType="location" - ✅ service.dart: Proper lifecycle management - starts at line 83, stops at lines 165, 229, 257, 263
3. Build Version Updated
- Version bumped to
300103037(android/app/build.gradle:52)
4. Improved Error Handling (service.dart:82-112)
The new nested try-catch structure is much more robust:
try {
await platform.invokeMethod('startForegroundService');
try {
// exact alarm
} catch (_) {
try {
// inexact alarm fallback
} catch (e2, s2) {
// cleanup and rethrow
await platform.invokeMethod('stopForegroundService');
}
}
}
⚠️ Critical Issues Found
1. 🚨 DUPLICATE ALARM SCHEDULING CODE (service.dart:114-137)
Lines 114-137 contain OLD CODE that should have been deleted!
After the new try-catch block (lines 82-112), there's a duplicate AndroidAlarmManager.oneShot() call at lines 114-121:
// Lines 114-121: THIS IS DUPLICATE CODE
await AndroidAlarmManager.oneShot(
kDefaultUpdateInterval,
kAlarmId,
LocationService._$task,
wakeup: true,
exact: true,
rescheduleOnReboot: true,
);
This is followed by another try-catch for inexact alarm (lines 122-137) which is also duplicate of the logic in lines 84-107.
Impact:
- Every time
start()is called, it tries to schedule the alarm twice - If the first scheduling succeeds, the second will overwrite it (harmless but wasteful)
- If the first scheduling fails and cleans up the service, the second scheduling will try again anyway
- This creates confusing control flow and wastes resources
Required Fix: Delete lines 114-137 entirely. They are duplicates of the logic already in lines 84-107.
⚠️ High Priority Issues
2. Missing EOF Newline (service.dart:400)
- The file ends at line 400 without a trailing newline
- This was noted in the previous review but hasn't been fixed
- Violates coding standards
- Fix: Add a newline at the end of the file
3. Redundant Foreground Service Start (service.dart:221)
Inside _$task(), the service is started again at line 221:
// 前景通知顯示
await LocationServiceManager.platform.invokeMethod('startForegroundService');
Issue:
- The service is already started in
start()at line 83 - When alarms trigger
_$task()(e.g., after the first cycle), the service might already be running - Multiple
startForegroundService()calls are generally safe (idempotent) but may cause brief notification flicker
Recommendation:
- If this is intentional (to ensure service is always running during task execution), add a comment explaining why
- Consider: Does the service stay running between alarm cycles, or should it stop/restart each time?
- Current behavior: Service starts in
start(), then restarts at each_$task()execution, then stops at task completion
Current flow per cycle:
- First call to
start(): Service starts (line 83) → Alarm scheduled → Task runs immediately - Task execution: Service starts again (line 221) → Work done → Service stops (line 257)
- Next alarm fires: Service starts (line 221) → Work done → Service stops (line 257)
This seems intentional - the service only runs during actual location updates, not continuously. If so, this is acceptable but could use a clarifying comment.
💭 Medium Priority - Consider whes1015's Suggestion
User whes1015 suggested (in comments):
"定位死掉還有一種可能,就是 task 意外死掉,或是被系統提前殺死,導致下一個週期沒辦法建立,可以試試看建立一個更長的週期(1小時)當成備用。"
Translation:
"Location might die because the task unexpectedly dies or is killed by the system early, preventing the next cycle from being established. Try creating a longer backup cycle (1 hour)."
Analysis: This is a valid concern. Current implementation has a potential failure mode:
- If
_$task()crashes/is killed before calling_rescheduleAlarm()(line 250) - The next alarm never gets scheduled
- Location updates stop permanently until the user manually restarts
Potential Solutions:
Option A: Backup Alarm (whes1015's suggestion) Create a secondary alarm with a longer interval (1 hour) as a safety net:
static const int kBackupAlarmId = 888889;
// In start(), schedule both:
await AndroidAlarmManager.periodic(
Duration(hours: 1),
kBackupAlarmId,
LocationService._$task,
wakeup: true,
rescheduleOnReboot: true,
);
Option B: Periodic Instead of OneShot
Use AndroidAlarmManager.periodic() instead of oneShot():
- Guarantees next execution even if current task fails
- Trade-off: Less flexible interval adjustment based on movement
Option C: WatchDog Pattern
Schedule the next alarm at the START of _$task(), not at the end:
static Future<void> _$task() async {
try {
// Schedule next alarm FIRST
await LocationServiceManager._rescheduleAlarm(/* current interval */);
// Then do the work
// ...
}
}
Recommendation:
- Consider implementing Option A (backup alarm) as it's the safest
- Or at minimum, ensure
_rescheduleAlarm()is in a finally block - This addresses a real reliability concern for background services on Android
📋 Low Priority Issues
4. Hardcoded Chinese Text (LocationForegroundService.kt:24)
- "正在更新定位…" is hardcoded
- Should use Android string resources for i18n
- Minor issue - can be addressed later
5. No PendingIntent on Notification (LocationForegroundService.kt:22-28)
- Tapping notification does nothing
- Could add PendingIntent to open the app
- Minor UX enhancement
6. Mixed Language Comments (service.dart)
- Lines 24, 82, 164, 220, 256 have Chinese comments
- Rest of codebase appears to use English
- Acceptable if team prefers mixed language
📊 Comparison with Previous Reviews
Previous Review Issues:
- ❌ Duplicate alarm scheduling → ✅ Partially fixed (new code is good, but old code not deleted)
- ❌ Missing EOF newline → ❌ Still not fixed
- ❌ Service leak on alarm failure → ✅ Fixed (line 105 cleanup)
New Issues Found:
- 🚨 Critical: Lines 114-137 are duplicate code that must be removed
- ⚠️ Important: Consider backup alarm mechanism (whes1015's suggestion)
🧪 Testing Recommendations
Before merging, verify:
Functional:
- [ ] Remove duplicate code (lines 114-137) and test alarm scheduling still works
- [ ] Service starts and shows notification during location updates
- [ ] Service stops and notification disappears after update completes
- [ ] Exact alarm works on devices with SCHEDULE_EXACT_ALARM permission
- [ ] Inexact alarm fallback works on restricted devices
- [ ] Service properly cleans up on startup errors
Edge Cases:
- [ ] What happens if
_$task()crashes before rescheduling? (whes1015's concern) - [ ] Service behavior across device reboot with
rescheduleOnReboot: true - [ ] Multiple rapid location toggles don't cause service leaks
- [ ] Battery optimization doesn't kill the service unexpectedly
🎯 Final Verdict
Status: ⚠️ CHANGES REQUIRED
Critical Issues (Must Fix):
- Delete duplicate code at lines 114-137 - This is essential, the code is duplicated and creates confusing control flow
- Add EOF newline at line 400
High Priority (Strongly Recommended): 3. Consider implementing backup alarm mechanism (whes1015's suggestion) to prevent permanent location update failure
Strengths:
- ✅ Proper foreground service implementation
- ✅ Good error handling in the new try-catch block (lines 82-112)
- ✅ Service cleanup on failure
- ✅ Correct Android manifest and MethodChannel setup
The core implementation is solid, but the duplicate code at lines 114-137 must be removed before merging. The backup alarm suggestion should also be seriously considered for production reliability.
--- | | Branch: fix/auto-location
Claude finished @lowrt's task —— View job
Code Review Progress
- [x] Read repository guidelines (CLAUDE.md not found - proceeding with standard review)
- [x] Review all changed files
- [x] Check if previous review issues were addressed
- [x] Analyze backup alarm suggestion from whes1015
- [x] Provide comprehensive feedback
Code Review - Fourth Iteration
I've reviewed this PR's latest changes (commits up to build 300103039). Great news - significant improvements have been made since the last review! 🎉
✅ Critical Issues RESOLVED!
The major issues from the previous review have been FIXED:
-
✅ Duplicate alarm scheduling code removed (lib/core/service.dart)
- The duplicate code at lines 114-137 mentioned in the previous review has been completely removed
- Clean, single code path for alarm scheduling in
start()(lines 92-122) - Proper nested try-catch: exact alarm first (lines 102-110), fallback to inexact (lines 111-119)
-
✅ Improved code structure
- Better documentation with clear flow explanation (lines 20-28)
- Chinese comments added for clarity (lines 33, 48, 61, 159, etc.)
- More concise error handling
- Notification ID changed from 888888 to 888999 to match native implementation
-
✅ Service lifecycle properly managed
- Native foreground service starts at line 229 in
_$task() - Service stops at lines 245, 280, 294 with proper error handling
- No more duplicate service starts
- Native foreground service starts at line 229 in
📊 Current Implementation Summary
Architecture: The implementation now correctly uses:
- AlarmManager to trigger periodic tasks
- Native ForegroundService (LocationForegroundService.kt) that runs ONLY during location updates
- One-shot execution pattern: Service starts → Location update → Service stops → Alarm rescheduled
Changed Files Analysis:
-
android/app/build.gradle ✅
- Version: 300103039 (up from initial 300103035)
-
android/app/src/main/AndroidManifest.xml ✅
- Service properly declared (lines 59-63)
- Correct
foregroundServiceType="location" - All required permissions present
-
android/app/src/main/kotlin/com/exptech/dpip/LocationForegroundService.kt ✅
- Clean, minimal implementation
- Uses
IMPORTANCE_MINfor notification channel - Returns
START_NOT_STICKY(line 35) - appropriate for one-shot tasks -
IMPORTANT NOTE: Changed from
START_STICKY(previous review) toSTART_NOT_STICKY- this is actually better for the current use case since the service is meant to stop after each task
-
android/app/src/main/kotlin/com/exptech/dpip/MainActivity.kt ✅
- Proper MethodChannel implementation
- Good error handling with try-catch blocks
-
lib/core/service.dart ✅
- Significantly improved structure
- Clear separation of concerns
- Better error handling in
_rescheduleAlarm()with inexact fallback (lines 126-146)
⚠️ Remaining Issues
High Priority
1. Missing EOF Newline (lib/core/service.dart:444)
- File ends at line 444 without a trailing newline
- This was noted in ALL previous reviews but still not fixed
- Violates standard coding conventions
- Required fix: Add a newline at the end of the file
2. whes1015's Backup Alarm Concern NOT Addressed User whes1015's comment raises a valid reliability concern:
"定位死掉還有一種可能,就是 task 意外死掉,或是被系統提前殺死,導致下一個週期沒辦法建立"
Translation: "Location might die if the task unexpectedly crashes or is killed by the system early, preventing the next cycle from being established"
Current Risk:
- If
_$task()crashes/is killed between lines 187-272 (before_rescheduleAlarm()at line 272) - The next alarm never gets scheduled
- Location updates stop permanently until user manually restarts
Current Mitigation:
- Lines 287-290 attempt to reschedule in the catch block ✅
- This helps BUT only if the exception is caught (won't help if process is killed by system)
Recommended Solutions:
Option A: Schedule Next Alarm FIRST (Safest approach)
Move _rescheduleAlarm() to the START of _$task():
static Future<void> _$task() async {
try {
DartPluginRegistrant.ensureInitialized();
await Preference.init();
// ... other initialization ...
// ⭐ Schedule NEXT alarm FIRST (before doing work)
final currentInterval = LocationServiceManager._getUpdateInterval();
await LocationServiceManager._rescheduleAlarm(currentInterval);
// Then do the location work (if task dies, next alarm is already scheduled)
// ...
}
}
Option B: Backup Periodic Alarm (whes1015's suggestion) Create a safety net with a longer periodic alarm:
static const int kBackupAlarmId = 888890;
// In start(), also schedule backup:
await AndroidAlarmManager.periodic(
Duration(hours: 1),
kBackupAlarmId,
LocationService._$task,
wakeup: true,
rescheduleOnReboot: true,
);
// In stop(), cancel both:
await AndroidAlarmManager.cancel(kAlarmId);
await AndroidAlarmManager.cancel(kBackupAlarmId);
My Recommendation: Implement Option A first (simple, no overhead). If reliability issues persist, add Option B as additional safety.
Medium Priority
3. Service Priority Changed to START_NOT_STICKY (LocationForegroundService.kt:35)
- Previous review noted
START_STICKY(line 27 in old version) -
Current code uses
START_NOT_STICKY(line 35) - This is actually correct for the current one-shot pattern ✅
- However, worth noting: If system kills the service mid-update, it won't restart
- Trade-off: Better for battery vs. reliability
4. Notification Has No PendingIntent (LocationForegroundService.kt:25-31)
- Tapping notification does nothing
- Consider adding PendingIntent to open the app:
val intent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this, 0, intent, PendingIntent.FLAG_IMMUTABLE
)
.setContentIntent(pendingIntent)
- Impact: Minor UX enhancement
5. Hardcoded Chinese Text (LocationForegroundService.kt:26-27)
- "正在更新位置" and "取得 GPS 位置中..." are hardcoded
- Should use Android string resources for i18n
- Impact: Minor - affects non-Chinese users
Low Priority
6. Mixed Language Comments (lib/core/service.dart)
- Lines 33, 43, 48, 61, 159 have Chinese comments
- Rest of codebase uses English
- Acceptable if team prefers mixed language documentation
7. Error Handling in _rescheduleAlarm (lib/core/service.dart:137-146)
- Catches exception from exact alarm, falls back to inexact ✅
- BUT: If inexact alarm also fails, error is silently ignored
- Consider logging the failure:
} catch (e2, s2) {
TalkerManager.instance.error('👷 reschedule inexact also failed', e2, s2);
}
🧪 Testing Recommendations
Before merging, please verify:
Critical Tests:
- [ ] Add the missing EOF newline and test that nothing breaks
- [ ] Test what happens if
_$task()is force-killed mid-execution (simulate system killing the process) - [ ] Verify alarm still reschedules after task crash
- [ ] Test on devices with aggressive battery optimization (Xiaomi, Huawei, etc.)
Functional Tests:
- [ ] Location updates work correctly with foreground service notification
- [ ] Notification appears/disappears at correct times
- [ ] Exact alarm works on devices with SCHEDULE_EXACT_ALARM permission
- [ ] Inexact alarm fallback works on restricted devices
- [ ] Service behavior across device reboot with
rescheduleOnReboot: true - [ ] Multiple rapid location toggles don't cause issues
Edge Cases:
- [ ] Watch displays notifications correctly (mentioned in PR description)
- [ ] Service properly stops when user disables auto-location
- [ ] No service leaks or zombie alarms
🎯 Final Verdict
Status: ✅ Approve with Minor Fixes
Strengths:
- ✅ All critical issues from previous reviews have been addressed
- ✅ Duplicate code removed - clean single code path
- ✅ Proper foreground service implementation
- ✅ Better code structure and documentation
- ✅ Improved error handling with exact/inexact alarm fallback
- ✅ Correct use of START_NOT_STICKY for one-shot pattern
Required Fixes (Trivial):
- [ ] Add newline at EOF (lib/core/service.dart:444) - This has been requested in ALL previous reviews
Strongly Recommended (Reliability):
- [ ] Address whes1015's concern by implementing Option A (schedule next alarm first) or Option B (backup alarm)
- [ ] Add logging for inexact alarm fallback failure
Nice to Have:
- [ ] Add PendingIntent to notification
- [ ] Internationalize notification text
- [ ] Add error logging for rescheduling failures
📈 Comparison with Previous Reviews
| Issue | Review 1 | Review 2 | Review 3 | Current |
|---|---|---|---|---|
| Missing service implementation | ❌ | ✅ | ✅ | ✅ |
| Duplicate alarm scheduling | ❌ | ❌ | ❌ | ✅ FIXED |
| Missing EOF newline | ❌ | ❌ | ❌ | ❌ Still missing |
| Service leak on failure | ❌ | ✅ | ✅ | ✅ |
| Backup alarm mechanism | N/A | N/A | ⚠️ Suggested | ⚠️ Not implemented |
Progress: Excellent improvement! Only 2 remaining issues: trivial EOF newline + reliability enhancement suggestion.
Summary
This PR has come a long way and is now in very good shape. The core implementation is solid, the major issues are resolved, and the code is clean.
The EOF newline is a trivial fix that should be done before merge (it's been requested 4 times now! 😅).
The backup alarm mechanism is a reliability enhancement worth considering, especially for production use with potentially aggressive battery optimization on various Android devices. whes1015's concern is valid - if you've experienced location updates stopping mysteriously in testing, this could be the cause.
Great work on addressing the previous feedback! 👏
計時器加上 claude 給的 b 方案
@claude review
Claude finished @lowrt's task —— View job
Code Review Progress
- [x] Read repository guidelines (CLAUDE.md not found - proceeding with standard review)
- [x] Review all changed files
- [x] Check if backup alarm (Option B) was implemented
- [x] Check if EOF newline was added
- [x] Analyze new changes and provide feedback
Code Review - Fifth Iteration
I've reviewed the latest changes to this PR (build 300103045). This review shows significant changes from the previous iteration!
🎯 Major Architectural Change Detected
CRITICAL FINDING: The Android LocationForegroundService implementation has been completely reverted!
Looking at the git history:
- Commit
3fd343b: LocationForegroundService.kt was implemented (52 lines) - Commit
09eeebd("Revert"): LocationForegroundService.kt was removed (-52 lines) - Current state: No native Android foreground service implementation exists
Impact: This PR has gone back to using AwesomeNotifications with NotificationCategory.Service instead of a real Android ForegroundService.
✅ What Was Successfully Implemented
1. Backup Alarm Mechanism ✅ (Option B from previous review)
Per whes1015's comment "計時器加上 claude 給的 b 方案" (Timer added with Claude's option B):
Implementation (lib/core/service.dart:115-121):
await AndroidAlarmManager.periodic(
Duration(hours: 1),
kBackupAlarmId,
LocationService._$task,
wakeup: true,
rescheduleOnReboot: true,
);
Analysis:
- ✅ New constant
kBackupAlarmId = 888890added (line 25) - ✅ Backup periodic alarm schedules every 1 hour
- ✅
stop()now cancels both alarms (lines 148-149) - ✅ This addresses the reliability concern from previous reviews
Potential Issue: The backup alarm runs in parallel with the primary alarm, meaning:
- Primary alarm: Dynamic interval (5-60 minutes) based on movement
- Backup alarm: Fixed 1-hour interval
- If primary alarm is working, backup alarm is redundant overhead
- Consider checking if primary alarm executed recently before doing full work in backup
2. EOF Newline Finally Added ✅
MainActivity.kt now has proper EOF newline (line 5 in diff)! This was requested in FOUR previous reviews. Great!
3. Code Cleanup ✅
- Removed inline documentation comments (reduces verbosity)
- Better formatting for long expressions
- Removed unnecessary blank lines
- More concise code structure
⚠️ Critical Issues
1. 🚨 MISLEADING PR TITLE AND MANIFEST
PR Title: "Use ForegroundService to show auto location notify"
Reality: There is NO Android ForegroundService implementation in the current code!
Evidence:
-
LocationForegroundService.ktwas reverted and removed -
MainActivity.ktis now just 5 lines (no MethodChannel for service start/stop) -
AndroidManifest.xmldeclares the service (lines 59-63) but the class doesn't exist - The app uses
AwesomeNotificationswithNotificationCategory.Service(service.dart:258)
Impact:
- ❌ The app will crash at runtime when the manifest tries to instantiate
LocationForegroundService - ❌ Android will fail to find the service class and throw
ClassNotFoundException - ❌ This is a critical bug that will prevent the location service from working
Proof:
<service
android:name=".LocationForegroundService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="location"/>
This references a class that does not exist in the codebase!
2. 🚨 PHANTOM SERVICE DECLARATION
The AndroidManifest.xml was not reverted along with the service implementation.
Required Fix: Either:
- Option A: Remove the service declaration from AndroidManifest.xml (lines 59-63)
- Option B: Re-add the LocationForegroundService.kt implementation
- Option C: Update PR title to reflect reality: "Add backup alarm for location tracking reliability"
Currently, the manifest references a non-existent class, which will cause runtime errors.
⚠️ High Priority Issues
3. Backup Alarm Always Runs (service.dart:115-121)
The backup alarm runs every hour regardless of whether the primary alarm is working.
Concerns:
- Battery drain: Unnecessary wakeups every hour even when primary alarm works fine
- Redundant work: If primary alarm executed 10 minutes ago, backup alarm does duplicate work
- No coordination: Both alarms can execute simultaneously
Recommendations:
Option A - Add timestamp check:
// At start of _$task()
static const String _kPrefKeyLastExecution = 'location_last_execution';
static Future<void> _$task() async {
// Check if recently executed by primary alarm
final lastExecution = Preference.instance.getInt(_kPrefKeyLastExecution);
if (lastExecution != null) {
final timeSinceLastRun = DateTime.now().millisecondsSinceEpoch - lastExecution;
if (timeSinceLastRun < Duration(minutes: 50).inMilliseconds) {
// Primary alarm is working, backup can skip
return;
}
}
// Do work...
// Update timestamp after successful completion
await Preference.instance.setInt(_kPrefKeyLastExecution, DateTime.now().millisecondsSinceEpoch);
}
Option B - Only schedule backup after failure: Instead of always running backup, only schedule it when primary alarm fails to reschedule.
Current behavior: Backup always runs → unnecessary battery usage Better behavior: Backup only runs if primary fails → minimal overhead
4. No Error Handling for Backup Alarm (service.dart:115-121)
If the AndroidAlarmManager.periodic() call fails, the error is silently ignored (no try-catch).
Impact: If backup alarm fails to schedule, the safety net doesn't exist but code thinks it does.
Recommendation: Add error handling:
try {
await AndroidAlarmManager.periodic(
Duration(hours: 1),
kBackupAlarmId,
LocationService._$task,
wakeup: true,
rescheduleOnReboot: true,
);
} catch (e, s) {
TalkerManager.instance.warning('👷 backup alarm scheduling failed', e, s);
// Consider: should we fail the entire start() if backup can't be scheduled?
}
📊 Comparison with Previous Reviews
| Issue | Review 2 | Review 3 | Review 4 | Current (Review 5) |
|---|---|---|---|---|
| LocationForegroundService exists | ✅ Added | ✅ | ✅ | ❌ REVERTED |
| Manifest declares service | ✅ | ✅ | ✅ | ⚠️ Orphaned declaration |
| MainActivity MethodChannel | ✅ | ✅ | ✅ | ❌ REVERTED |
| Backup alarm mechanism | ❌ | ❌ Suggested | ⚠️ Not implemented | ✅ IMPLEMENTED |
| EOF newline | ❌ | ❌ | ❌ | ✅ FIXED |
| Duplicate alarm code | ❌ | ❌ | ✅ Fixed | ✅ |
Summary: This PR has regressed significantly. The previous implementations of ForegroundService have been removed, but:
- The AndroidManifest still declares the non-existent service (will crash)
- The PR title is now misleading (claims to use ForegroundService but doesn't)
- The backup alarm was successfully added (good!)
🔍 What Actually Changed in This PR
Looking at the git diff vs origin/main:
Changes That Are Good:
- ✅ Backup alarm added - 1-hour periodic alarm as safety net
- ✅ EOF newline in MainActivity.kt - Proper file ending
- ✅ Code formatting - Better readability with consistent formatting
- ✅ Build version bump - 300103027 → 300103045
Changes That Are Problematic:
- ❌ Manifest declares non-existent service - Will crash at runtime
- ❌ Removed inline documentation - Makes code less self-documenting
- ⚠️ Backup alarm always runs - Battery concerns
📝 Testing Recommendations
CRITICAL - Test First:
- ⚠️ Install this build on a device and enable auto-location
- ⚠️ Check logcat for ClassNotFoundException related to LocationForegroundService
- ⚠️ Verify the app doesn't crash when location service starts
If the app works without crashing, it means Android is ignoring the unused service declaration (possible but risky).
Functional Tests:
- [ ] Backup alarm executes after 1 hour
- [ ] Primary alarm still works with dynamic intervals
- [ ] Both alarms stop when auto-location is disabled
- [ ] Location updates survive aggressive battery optimization
- [ ] Service restarts after device reboot
🎯 Final Verdict
Status: ⚠️ CHANGES REQUIRED - Critical Bug
Critical Issues (MUST FIX):
-
Remove orphaned service declaration from AndroidManifest.xml (lines 59-63)
- The service class doesn't exist, this will cause crashes
-
Update PR title to accurately reflect changes:
- Current (misleading): "Use ForegroundService to show auto location notify"
- Suggested: "Add backup alarm for location tracking reliability" or "Improve location service reliability with backup timer"
High Priority (Should Fix):
- Add timestamp check to prevent backup alarm from doing redundant work
- Add error handling for backup alarm scheduling
- Consider re-adding inline documentation for maintainability
Strengths:
- ✅ Backup alarm successfully implemented (addresses whes1015's concern)
- ✅ EOF newline finally added (after 4 reviews! 🎉)
- ✅ Code is cleaner and more concise
- ✅ No more duplicate alarm scheduling
💡 Recommendations
For this PR:
- Remove lines 59-63 from AndroidManifest.xml (the orphaned service declaration)
- Update PR title and description to reflect actual changes (backup alarm, not ForegroundService)
- Consider adding timestamp-based coordination between primary and backup alarms
- Add error handling for backup alarm scheduling
For future PRs (if you want real ForegroundService):
- Consider re-implementing LocationForegroundService.kt properly
- The previous implementation (commit 3fd343b) was actually quite good
- Real ForegroundService provides better protection against system killing the app
- But current approach with AwesomeNotifications might be sufficient if it works
🤔 Question for the Team
Why was LocationForegroundService reverted? (commit 09eeebd)
Understanding the reason will help determine the right path forward:
- Was it causing crashes? → Need to fix the implementation
- Was it unnecessary? → Remove manifest declaration and update PR title
- Was it WatchOS compatibility? → Need platform-specific handling
- Was it notification conflicts? → Need better notification management
The PR description mentions "修正手錶顯示通知" (fix watch display notification), which might be related to the revert.
Recommendation: ❌ Do not merge until the orphaned service declaration is removed from AndroidManifest.xml
Once fixed: ✅ Can approve (the backup alarm implementation is good, just need to clean up the manifest and title)
@claude review bamboo0403 說 LocationForegroundService 移除,會變成一般通知,導致自動定位不明原因中斷
Claude finished @lowrt's task —— View job
Code Review Progress
- [x] Read all changed files
- [x] Check for LocationForegroundService.kt
- [x] Analyze AndroidManifest.xml service declaration
- [x] Review service.dart implementation
- [x] Understand location interruption issue
- [x] Provide comprehensive feedback
Code Review - Understanding the Location Interruption Issue
I've reviewed this PR and analyzed the specific concern raised by @bamboo0403 about location interruptions after removing LocationForegroundService. Here's my comprehensive analysis:
🔍 Critical Finding: Orphaned Service Declaration
The Issue:
- ✅ AndroidManifest.xml declares
LocationForegroundService(lines 59-63) - ❌ The implementation file
LocationForegroundService.ktdoes NOT exist - ⚠️ This creates an orphaned service declaration
Evidence from git history:
Based on previous review comments, LocationForegroundService.kt was implemented in an earlier commit but then reverted (commit 09eeebd). However, the manifest declaration was not reverted along with it.
Current Architecture: The PR now uses:
-
AwesomeNotificationswithNotificationCategory.Service(service.dart:258) -
AndroidAlarmManagerfor scheduling periodic tasks - No actual Android ForegroundService implementation
🎯 Why Location Updates Stop Without ForegroundService
@bamboo0403's observation is absolutely correct. Here's why removing the ForegroundService causes "不明原因中斷" (unexplained interruptions):
1. Android Background Execution Limits
Without a proper ForegroundService, the app is subject to aggressive background restrictions:
Without ForegroundService:
- ❌ AlarmManager can trigger the task
- ❌ But the background isolate may be killed mid-execution
- ❌ System treats the app as "background" priority
- ❌ Android's Doze mode and App Standby aggressively restrict background execution
- ❌ On devices with aggressive battery optimization (Xiaomi, Huawei, OPPO, etc.), background processes are killed within seconds
With ForegroundService:
- ✅ Notification indicates active work to the system
- ✅ Process priority elevated to "foreground"
- ✅ Protection from Doze mode restrictions
- ✅ System grants more CPU time and prevents immediate killing
- ✅ Better reliability on devices with aggressive battery optimization
2. Notification Type Differences
Current: AwesomeNotifications with NotificationCategory.Service
category: NotificationCategory.Service, // service.dart:258
- This is just a notification category hint
- Does NOT provide actual ForegroundService protection
- Can be dismissed by the system
- No process priority elevation
With Real ForegroundService:
startForeground(notificationId, notification)
- Creates a binding between service lifecycle and notification
- System cannot kill the service without user explicitly stopping it
- Provides legal "I'm doing important work" signal to Android
- Must be dismissed by calling
stopForeground()orstopSelf()
3. The Android 8.0+ Requirement
Since Android 8.0 (API 26), background services are heavily restricted:
- Apps cannot freely start background services
- Background execution time limits enforced
- Only ForegroundService with notification gets reliable background execution
Your app targets API 26+ (minSdkVersion 26), so this applies to all supported devices.
📊 Current PR Changes Analysis
✅ Good Changes:
-
Backup Alarm Added (service.dart:115-121)
- 1-hour periodic alarm as safety net
- Addresses the concern about task failures
- Good reliability improvement
-
EOF Newline Fixed (MainActivity.kt:5)
- Proper file ending added
-
Code Cleanup
- Better formatting
- More concise structure
❌ Critical Problems:
-
🚨 Orphaned Service Declaration in Manifest
<service android:name=".LocationForegroundService" android:enabled="true" android:exported="false" android:foregroundServiceType="location"/>- This references a non-existent class
- Android will look for
com.exptech.dpip.LocationForegroundServiceat runtime - May not crash immediately (Android might not instantiate until needed)
- But creates undefined behavior
-
🚨 Misleading Permissions The manifest still declares (lines 4-5):
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />- These are required for ForegroundService
- But the app doesn't actually use ForegroundService
- Creates confusion and false expectations
-
⚠️ No ForegroundService Protection
- Location updates rely on background execution
- Subject to Android's aggressive background restrictions
- This is why location updates stop unexpectedly
💡 Understanding the Problem
The core issue is Android's background execution model:
[Alarm Triggers] → [Background Isolate Starts] → [Gets Location] → [Updates Server]
↑
└─ Without ForegroundService:
System can kill this at ANY time!
What happens in practice:
- AlarmManager triggers at scheduled time ✅
- Dart background isolate starts executing
_$task()✅ - During execution (GPS acquisition, network call), Android decides: "This app is using too many resources in background" ⚠️
- System kills the process mid-execution ❌
- Location update incomplete, alarm may not be rescheduled ❌
- User sees: "自動定位不明原因中斷" (auto-location stops for unknown reason) ❌
With ForegroundService:
- AlarmManager triggers ✅
- Start ForegroundService + show notification ✅
- System: "OK, this app is doing foreground work" ✅
- Background isolate executes with protection ✅
- Work completes, reschedule alarm ✅
- Stop ForegroundService ✅
- Everything works reliably ✅
🎯 Recommendations
Option A: Re-implement ForegroundService (RECOMMENDED)
This is the proper Android solution for reliable background location updates:
- Re-add LocationForegroundService.kt (based on earlier commits):
class LocationForegroundService : Service() {
override fun onCreate() {
super.onCreate()
val notification = createNotification()
startForeground(NOTIFICATION_ID, notification)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_NOT_STICKY // Don't restart if killed
}
override fun onBind(intent: Intent?): IBinder? = null
private fun createNotification(): Notification {
// Create channel and notification
}
}
- Update MainActivity.kt to control the service:
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger,
"com.exptech.dpip/location").setMethodCallHandler { call, result ->
when (call.method) {
"startForegroundService" -> {
val intent = Intent(this, LocationForegroundService::class.java)
startForegroundService(intent)
result.success(null)
}
"stopForegroundService" -> {
val intent = Intent(this, LocationForegroundService::class.java)
stopService(intent)
result.success(null)
}
else -> result.notImplemented()
}
}
}
}
- Update service.dart to use the foreground service:
static Future<void> _$task() async {
try {
// Start foreground service at beginning
await LocationServiceManager.platform.invokeMethod('startForegroundService');
// Do location work...
// Stop foreground service at end
await LocationServiceManager.platform.invokeMethod('stopForegroundService');
} catch (e, s) {
// Ensure service stops on error
await LocationServiceManager.platform.invokeMethod('stopForegroundService');
rethrow;
}
}
Why this works:
- ✅ Service runs ONLY during actual location updates (seconds/minutes)
- ✅ Not a persistent foreground service (minimizes user annoyance)
- ✅ Provides process protection when needed
- ✅ Complies with Android's background execution requirements
- ✅ Works reliably on all devices, including those with aggressive battery optimization
Option B: Remove Manifest Declaration (NOT RECOMMENDED)
If you decide not to use ForegroundService:
- Remove service declaration from AndroidManifest.xml (lines 59-63)
- Remove foreground service permissions (lines 4-5)
- Update PR title to reflect reality
- Accept that location updates may be unreliable on some devices
Why this is not recommended:
- ❌ Doesn't solve the reliability problem
- ❌ Users will continue experiencing interruptions
- ❌ Backup alarm helps but doesn't fully solve the issue
- ❌ Some devices will kill background work within seconds
📱 Real-World Impact
Devices Most Affected:
- Xiaomi (MIUI): Very aggressive background restrictions
- Huawei/Honor (EMUI): Kills background apps aggressively
- OPPO/OnePlus (ColorOS): Auto-kills background tasks
- Samsung: Less aggressive but still applies Doze mode
- Stock Android: Follows standard restrictions
Without ForegroundService:
- Users on aggressive OEM ROMs will experience frequent interruptions
- Location updates may work on some devices but fail on others
- Inconsistent user experience across Android ecosystem
With ForegroundService:
- Reliable across all Android devices
- Works even with aggressive battery optimization
- Provides consistent user experience
🎯 Final Verdict
Status: ⚠️ CHANGES REQUIRED
Critical Issues:
-
🚨 Remove orphaned service declaration from AndroidManifest.xml (lines 59-63)
- Current state: Declares non-existent service
- Risk: Undefined behavior, potential crashes
-
🚨 Decision needed: ForegroundService or not?
- Recommended: Re-implement ForegroundService (Option A)
- Alternative: Remove all ForegroundService references (Option B)
- Do NOT: Keep the current hybrid state
Why @bamboo0403 is Correct:
@bamboo0403 的觀察是完全正確的:
- 沒有 ForegroundService = 普通通知 = 背景執行限制
- 系統可以隨時終止背景工作
- 導致自動定位「不明原因中斷」
- 這不是 bug,這是 Android 8.0+ 的設計
The backup alarm (backup timer) is a good addition, but it's a workaround, not a solution to the root cause. The real problem is Android's background execution restrictions, which only ForegroundService can bypass.
📝 Recommended Action Plan
To fix this PR:
-
Short-term (minimal fix):
- Remove lines 59-63 from AndroidManifest.xml
- Update PR title: "Add backup alarm for location reliability"
- Accept potential reliability issues on some devices
-
Long-term (proper fix):
- Re-implement LocationForegroundService.kt
- Add MethodChannel integration in MainActivity.kt
- Update service.dart to start/stop service during task execution
- Keep the backup alarm as additional safety net
- Update PR title: "Improve location service reliability with foreground service and backup timer"
My recommendation: Go with the long-term solution. The previous ForegroundService implementation (from earlier commits) was actually good and solved a real problem. Re-adding it will provide the reliability users need.
📈 Summary
| Aspect | Current State | With ForegroundService |
|---|---|---|
| Reliability | ⚠️ Inconsistent | ✅ Reliable |
| Battery impact | ✅ Lower | ⚠️ Slightly higher |
| User experience | ❌ Random interruptions | ✅ Consistent |
| Android compliance | ⚠️ Works around restrictions | ✅ Follows best practices |
| OEM compatibility | ❌ Poor on MIUI/EMUI | ✅ Good on all devices |
The trade-off is clear:
- Without ForegroundService: Better battery, but unreliable
- With ForegroundService: Slightly more battery use, but reliable
For a location tracking feature, reliability should be the priority.