Местоположение фона iOS работает в отладке, но не в выпуске (Flutter)IOS

Программируем под IOS
Ответить
Anonymous
 Местоположение фона iOS работает в отладке, но не в выпуске (Flutter)

Сообщение Anonymous »

Я использую Flutter с Flutter_background_service и Geolocator для получения обновлений местоположения в фоновом режиме.
В режиме отладки , фоновое местоположение работает нормально, даже когда приложение минимизировано или заблокирован экран. Любые обновления местоположения фона.

Код: Выделить всё

UIBackgroundModes

fetch
location
remote-notification
processing


NSLocationAlwaysAndWhenInUseUsageDescription
Your location is needed even when the app is in the background to track trips.

NSLocationAlwaysUsageDescription
Your location is needed even when the app is in the background to track trips.

NSLocationTemporaryUsageDescriptionDictionary

LocationTracking
This app needs precise location for school bus tracking and safety monitoring purposes.


NSLocationWhenInUseUsageDescription
Your location is needed to track trips while the app is open.

BGTaskSchedulerPermittedIdentifiers

dev.flutter.background.refresh

backgorundservice

Код: Выделить всё

class BackgroundServiceController extends ChangeNotifier {
static final BackgroundServiceController _instance =
BackgroundServiceController._internal();
factory BackgroundServiceController() => _instance;
BackgroundServiceController._internal();
final FlutterBackgroundService _service = FlutterBackgroundService();

Future initializeService({
required int? disInterval,
required int? timeInterval,
}) async {
SessionController().setDistanceAndTimeInterval(
disInterval: disInterval.toString(),
timeInterval: timeInterval.toString(),
);

final isRunning = await _service.isRunning();
if (isRunning) {
await Future.delayed(const Duration(seconds: 1));
_service.invoke('setData');
return;
}

const AndroidNotificationChannel channel = AndroidNotificationChannel(
'my_foreground',
'MY FOREGROUND SERVICE',
description:
'This channel is used for important notifications.',
importance: Importance.low,
);

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

if (Platform.isIOS || Platform.isAndroid) {
await flutterLocalNotificationsPlugin.initialize(
const InitializationSettings(
iOS: DarwinInitializationSettings(),
android: AndroidInitializationSettings('logo'),
),
);
}
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin
>()
?.createNotificationChannel(channel);
await _service.configure(
androidConfiguration: AndroidConfiguration(
onStart: onStart,
autoStart: true,
isForegroundMode: true,
autoStartOnBoot: true,
notificationChannelId: 'my_foreground',
initialNotificationTitle: 'Location Service',
initialNotificationContent: 'Initializing...',
foregroundServiceNotificationId: 888,

foregroundServiceTypes: [AndroidForegroundType.location],
),
iosConfiguration: IosConfiguration(
autoStart: true,
onForeground: onStart,
onBackground: onIosBackground,
),
);

try {
await _service.startService();
} catch (e) {

}
while (!(await _service.isRunning())) {
await Future.delayed(const Duration(milliseconds: 200));
}
await Future.delayed(const Duration(seconds: 3));
_service.invoke('setData');
}

Future stopService() async {
final isRunning = await _service.isRunning();
if (isRunning) {
_service.invoke("stopService");
} else {
}
}

Future  isServiceRunning() async {
return await _service.isRunning();
}
}

@pragma('vm:entry-point')
void onStart(ServiceInstance service) async {
// DartPluginRegistrant.ensureInitialized();

WidgetsFlutterBinding.ensureInitialized();
await AppConstants.init();
await SessionController().init();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final disInterval = SessionController().disInterval ?? 20;
final timeInterval = SessionController().timeInterval ?? 10;
StreamSubscription
? positionStream;
final homeViewModel = HomeViewModel();

void startLocationTracking() async {
if (positionStream != null) {
return;
}

DateTime? lastSentTime;
positionStream =
Geolocator.getPositionStream(
locationSettings: const LocationSettings(
distanceFilter: 0,
accuracy: LocationAccuracy.bestForNavigation,
),
).listen((position) async {
final now = DateTime.now();

if (lastSentTime == null ||
now.difference(lastSentTime!).inSeconds >= (timeInterval)) {
lastSentTime = now;

try {
await homeViewModel.pushLiveLocation(position: position);
} catch (e) {
}
} else {
}
});
}

service.on('stopService').listen((event) async {
await positionStream?.cancel();
positionStream = null;
await service.stopSelf();
});

service.on('setData').listen((data) async {
final disInterval = SessionController().disInterval ?? 20;
final timeInterval = SessionController().timeInterval ?? 10;

await Future.delayed(const Duration(seconds: 5));
startLocationTracking();
});

if (service is AndroidServiceInstance &&
await service.isForegroundService()) {
flutterLocalNotificationsPlugin.show(
888,

'Tracking location in background',
'Background location is on to keep the app up-tp-date with your location. This is required for main features to work properly when the app is not running.',
const NotificationDetails(
android: AndroidNotificationDetails(
'my_foreground',
'MY FOREGROUND SERVICE',
icon: 'ic_stat_notification',
ongoing: true,
styleInformation: BigTextStyleInformation(
'Background location is on to keep the app up-to-date with your location. '
'This is required for main features to work properly when the app is not running.',
contentTitle: 'Tracking location in background',
htmlFormatContent: true,
),
),
),
);

// service.setForegroundNotificationInfo(
//   title: "Location Tracking",
//   content: "Tracking your location in background",
// );
}
}

@pragma('vm:entry-point')
Future onIosBackground(ServiceInstance service) async {
// DartPluginRegistrant.ensureInitialized();
WidgetsFlutterBinding.ensureInitialized();
await AppConstants.init();
await SessionController().init();
final homeViewModel = HomeViewModel();
try {
final disInterval = SessionController().disInterval ?? 20;

final sub =
Geolocator.getPositionStream(
locationSettings: const LocationSettings(
distanceFilter: 0,

accuracy: LocationAccuracy.bestForNavigation,
),
).listen((position) async {
try {
await homeViewModel.pushLiveLocation(position: position);
} catch (e) {
}
});

await Future.delayed(const Duration(seconds: 30));
await sub.cancel();
} catch (e) {
}

return true;
}
Я также проверил, что приложение всегда разрешает разрешение на местоположение в настройках iOS


Подробнее здесь: https://stackoverflow.com/questions/797 ... se-flutter
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»