Search code examples
flutterdartbloc

how to make flutter cubit listen to changes in background?


so i want to know how i can make the flutter cubit bloc works in background for flutter ?

i tried to use this code to listen to changes and emit new location it's work only in forground

  location.onLocationChanged.listen((LocationData currentLocation) async {
     emit(currentLocation);
  });

even when i set enablebackground the cubit will stop working

location.enableBackgroundMode(enable: true);

is there a better way to implement it ?


Solution

  • this is what i end up doing , it's worked well , just move your logic away from blocbuilder and bloclistenr

    Location state

    // ignore_for_file: public_member_api_docs, sort_constructors_first
    part of 'location_cubit.dart';
    
    abstract class LocationState extends Equatable {
      @override
      List<Object> get props => [];
    }
    
    class LocationInitial extends LocationState {
      final double lat;
      final double lng;
      LocationInitial({
        required this.lat,
        required this.lng,
      });
      @override
      List<Object> get props => [lat, lng];
    }
    
    class Locationloading extends LocationState {
      Locationloading();
    }
    

    location cubit

    import 'dart:async';
    // ignore: depend_on_referenced_packages
    import 'package:bloc/bloc.dart';
    import 'package:equatable/equatable.dart';
    import 'package:hive/hive.dart';
    import 'package:location/location.dart';
    
    part 'location_state.dart';
    
    class LocationCubit extends Cubit<LocationState> {
      late StreamSubscription<LocationData> control;
      Location elocation = Location();
      LocationCubit() : super(LocationInitial(lat: 0, lng: 0)) {
        print("Init");
    
        elocation.changeSettings(interval: 8000, distanceFilter: 20);
        control = elocation.onLocationChanged
            .listen((LocationData location) => {inc(location)});
      }
    
      void inc(LocationData location) {
        /* This will get called on background and forground too
         , BUT UI get updated only in Forground 
         ( so all BlocBuilder / BlocListner will not be invoked in background
         all your logic should be here ( like call http or something)
         and when your app is back to forground it's will work ");
        */
        print("called on backgroud and forground");
        String nice = Hive.box('myBox').get('name');
        print(nice);
        emit(LocationInitial(
            lat: location.latitude!.toDouble(),
            lng: location.longitude!.toDouble()));
      }
    
      void pause() async {
        print("should be paused");
        emit(Locationloading());
        await elocation.enableBackgroundMode(enable: false);
        print("should be ok paused");
        control.pause();
        emit(LocationInitial(lat: 0, lng: 0));
      }
    
      void cont() async {
        emit(Locationloading());
        print("should be cont");
        await elocation.enableBackgroundMode(enable: true);
        print("should be ok cont");
        LocationData loca = await elocation.getLocation();
        control.resume();
        (LocationInitial(
            lat: loca.latitude!.toDouble(), lng: loca.longitude!.toDouble()));
      }
    
      @override
      Future<void> close() async {
        print("should be called");
        await elocation.enableBackgroundMode(enable: false);
        control.cancel();
        print("should be bye");
        return super.close();
      }
    }