getPermissionStream method

  1. @override
Stream<DeviceLocationPermission> getPermissionStream({
  1. Duration pollingInterval = const Duration(seconds: 1),
})
override

Implementation

@override
Stream<DeviceLocationPermission> getPermissionStream({
  Duration pollingInterval = const Duration(seconds: 1),
}) {
  final controller = StreamController<DeviceLocationPermission>.broadcast();
  StreamSubscription<dynamic>? nativeSub;
  Timer? timer;

  Future<void> emitCurrent() async {
    if (controller.isClosed) return;
    try {
      final permission = await checkPermission();
      if (!controller.isClosed) controller.add(permission);
    } on Exception catch (e) {
      if (!controller.isClosed) controller.addError(e);
    }
  }

  controller.onListen = () {
    timer = Timer.periodic(pollingInterval, (_) => emitCurrent());
    try {
      nativeSub = permissionUpdatesChannel
          .receiveBroadcastStream()
          .listen(
            (dynamic event) {
              final index = event as int;
              if (!controller.isClosed) {
                controller.add(DeviceLocationPermission.values[index]);
              }
            },
            onError: (_) {
              // Polling will keep the stream alive.
            },
          );
    } on Exception {
      // Event channel not implemented on the native side; polling covers it.
    }
    emitCurrent();
  };

  controller.onCancel = () {
    timer?.cancel();
    timer = null;
    nativeSub?.cancel();
    nativeSub = null;
  };

  return controller.stream;
}