feat: section 4 — Android battery optimization prompt
One-time prompt on first launch (Android only) directing the user to exclude bincio-rec from battery optimization. Uses the direct REQUEST_IGNORE_BATTERY_OPTIMIZATIONS system dialog with a fallback to the general settings page for OEMs that block the direct intent. Dismissal persisted in AsyncStorage so prompt never repeats.
This commit is contained in:
@@ -4,6 +4,7 @@ import * as Notifications from 'expo-notifications';
|
||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
||||
import { AppNavigator } from './src/navigation/AppNavigator';
|
||||
import { requestNotificationPermissions } from './src/services/gps';
|
||||
import { promptBatteryOptimizationIfNeeded } from './src/services/batteryOptimization';
|
||||
|
||||
// Show notifications even when the app is in the foreground (iOS suppresses by default)
|
||||
Notifications.setNotificationHandler({
|
||||
@@ -18,6 +19,7 @@ Notifications.setNotificationHandler({
|
||||
export default function App() {
|
||||
useEffect(() => {
|
||||
requestNotificationPermissions();
|
||||
promptBatteryOptimizationIfNeeded();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
@@ -117,9 +117,9 @@ Items below are what remains before v1 is shippable.
|
||||
- [x] **Permission request** — `requestNotificationPermissions()` called in `App.tsx` on mount; foreground notification handler set at module level so iOS shows banners while app is active
|
||||
- [x] **Milestone tracker** — module-level `runningDistanceMeters` / `lastNotifiedKm` / `prevPoint` in `gps.ts`, reset on each `startGpsRecording()`; each incoming location adds haversine distance and fires a notification when a new km is crossed, gated on the `kmNotifications` AsyncStorage setting
|
||||
|
||||
### 4 — Android battery optimization prompt (1–2 hours)
|
||||
### 4 — Android battery optimization prompt ✅
|
||||
|
||||
- [ ] On first launch, detect if the app is affected by battery optimization (`expo-intent-launcher`) and show a one-time prompt directing the user to whitelist bincio-rec; persist dismissal in AsyncStorage so it only shows once
|
||||
- [x] `src/services/batteryOptimization.ts` — Android-only, one-time prompt (dismissed flag in AsyncStorage); uses `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` intent to open the system dialog for bincio-rec directly; falls back to `IGNORE_BATTERY_OPTIMIZATION_SETTINGS` (general page) on OEMs that block the direct intent; called from `App.tsx` on mount alongside notification permission request
|
||||
|
||||
### 5 — Map (optional upgrade)
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Platform, Alert } from 'react-native';
|
||||
import * as IntentLauncher from 'expo-intent-launcher';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
const PROMPT_SHOWN_KEY = 'batteryOptPromptShown';
|
||||
|
||||
export async function promptBatteryOptimizationIfNeeded(): Promise<void> {
|
||||
if (Platform.OS !== 'android') return;
|
||||
|
||||
const shown = await AsyncStorage.getItem(PROMPT_SHOWN_KEY);
|
||||
if (shown) return;
|
||||
|
||||
await AsyncStorage.setItem(PROMPT_SHOWN_KEY, 'true');
|
||||
|
||||
Alert.alert(
|
||||
'Allow background GPS',
|
||||
'To record accurately while the screen is off, bincio-rec needs to be excluded from battery optimization.\n\nTap "Open settings", find bincio-rec, and select "Don\'t optimize".',
|
||||
[
|
||||
{
|
||||
text: 'Open settings',
|
||||
onPress: () =>
|
||||
IntentLauncher.startActivityAsync(
|
||||
IntentLauncher.ActivityAction.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
|
||||
{ data: 'package:com.bincio.rec' },
|
||||
).catch(() =>
|
||||
// Fallback: some OEMs don't support the direct intent — open the general page
|
||||
IntentLauncher.startActivityAsync(
|
||||
IntentLauncher.ActivityAction.IGNORE_BATTERY_OPTIMIZATION_SETTINGS,
|
||||
),
|
||||
),
|
||||
},
|
||||
{ text: 'Later', style: 'cancel' },
|
||||
],
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user