Fix beacon scanning reliability with warmup delay

- Add flutterBeacon.close before initializing to clear stale state
- Add 2-second Bluetooth warmup delay for radio initialization
- Extend scan duration to 5 seconds for reliable detection
- Ensure ACCESS_BACKGROUND_LOCATION permission is included

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-01-27 00:39:11 -08:00
parent c71432e91d
commit 0adb172b9e
3 changed files with 26 additions and 22 deletions

View file

@ -18,9 +18,8 @@
<!-- Allow basic foreground service (needed by beacon library for scanning) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- Remove location-specific foreground service and background location (these require video documentation) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" tools:node="remove" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" />
<!-- Background location required for beacon scanning -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<application
android:label="Payfrit"

View file

@ -30,22 +30,19 @@ class PayfritApp extends StatelessWidget {
ChangeNotifierProvider<AppState>(create: (_) => AppState()),
],
child: Api.isDev
? Banner(
message: "DEV",
location: BannerLocation.topEnd,
color: Colors.orange,
textStyle: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.bold,
color: Colors.white,
),
layoutDirection: TextDirection.ltr,
child: MaterialApp(
scaffoldMessengerKey: rootScaffoldMessengerKey,
debugShowCheckedModeBanner: false,
title: "Payfrit DEV",
initialRoute: AppRoutes.splash,
routes: AppRoutes.routes,
? Directionality(
textDirection: TextDirection.ltr,
child: Banner(
message: "DEV",
location: BannerLocation.topEnd,
color: Colors.orange,
child: MaterialApp(
scaffoldMessengerKey: rootScaffoldMessengerKey,
debugShowCheckedModeBanner: false,
title: "Payfrit DEV",
initialRoute: AppRoutes.splash,
routes: AppRoutes.routes,
),
),
)
: MaterialApp(

View file

@ -246,11 +246,18 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
// Initialize beacon scanning
try {
// Close any existing ranging streams first
await flutterBeacon.close;
await flutterBeacon.initializeScanning;
// Only add delay if permissions were freshly granted (Bluetooth subsystem needs warmup)
// Always add warmup delay - Bluetooth adapter needs time to initialize
print('[Splash] 🔄 Bluetooth warmup...');
await Future.delayed(const Duration(milliseconds: 2000));
// Extra delay if permissions were freshly granted
if (_permissionsWereFreshlyGranted) {
print('[Splash] 🔄 Fresh permissions - adding Bluetooth warmup delay');
print('[Splash] 🆕 Fresh permissions - adding extra warmup');
await Future.delayed(const Duration(milliseconds: 1500));
}
@ -274,7 +281,8 @@ class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMix
}
});
await Future.delayed(const Duration(milliseconds: 2000));
// Scan for 5 seconds to ensure we catch beacons
await Future.delayed(const Duration(milliseconds: 5000));
await subscription.cancel();
// Now lookup business info for found beacons