Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

headless with state management or providers #167

Closed
niypoo opened this issue Dec 25, 2019 · 19 comments
Closed

headless with state management or providers #167

niypoo opened this issue Dec 25, 2019 · 19 comments
Labels

Comments

@niypoo
Copy link

niypoo commented Dec 25, 2019

Your Environment

  • Plugin version: ^1.5.0
  • Platform: Android
  • OS version: androdi 10
  • Device manufacturer / model:
  • Flutter info (flutter doctor):
  • Plugin config:
  // Fired whenever a location is recorded
      bg.BackgroundGeolocation.onLocation((bg.Location location)=>onLocation(location,listsProvider), _onLocationError);

      print('[Background location init]');
      //BackGround Geoloacation init
      bg.State state = await bg.BackgroundGeolocation.ready(bg.Config(
        desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
        distanceFilter: distanceListener,
        stopOnTerminate: false,
        startOnBoot: true,
        enableHeadless: true,
        debug: false,
        logLevel: bg.Config.LOG_LEVEL_OFF,
      ));
      print('state.enabled ${state.enabled}');
      if (!state.enabled) bg.BackgroundGeolocation.start();
    }





in main.dart
        if(Platform.isAndroid){

          void headlessTask(bg.HeadlessEvent headlessEvent) async {
            print('[BackgroundGeolocation HeadlessTask]: $headlessEvent');
            ListsProvider  listsProvider = Provider.of<ListsProvider>(context, listen: false);
            // Implement a 'case' for only those events you're interested in.
            switch(headlessEvent.name) {
              case bg.Event.LOCATION:
                bg.Location location = headlessEvent.event;
                LocationListenerHelper.onLocation(location,listsProvider);
                print('- Location: $location');
                break;
            }
          }

          bg.BackgroundGeolocation.registerHeadlessTask(headlessTask);
        }

Expected Behavior

I'm trying to use headless in android it's work great but I need use Providers or state management with it to check my location in database but I can't figure out what the way once give me

I/flutter ( 9015): [BackgroundGeolocation _headlessCallbackDispather] ‼️ Callback error: NoSuchMethodError: No top-level getter 'headlessTask' declared.
I/flutter ( 9015): Receiver: top-level
I/flutter ( 9015): Tried calling: headlessTask

and once give me

E/flutter ( 9015): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'toRawHandle' was called on null.
E/flutter ( 9015): Receiver: null
E/flutter ( 9015): Tried calling: toRawHandle()

Context

in main.dart
main Function once
and I'm tried in myApp() function

@christocracy
Copy link
Member

Don't do this:

if(Platform.isAndroid){
   ...
}

@christocracy
Copy link
Member

christocracy commented Dec 26, 2019

And also make sure your void headlessTask() is not defined in the function void main(). Do it exactly as documented

📂 main.dart

// Headless function defined "in top level"
void headlessTask(bg.HeadlessEvent event) async {
  print('headlessTask');
}

void main() {
  runApp(YourApp());
  // Headless function registered within main()
  bg.BackgroundGeolocation.registerHeadlessTask(headlessTask);
}

@niypoo
Copy link
Author

niypoo commented Dec 27, 2019

@christocracy thanks for reply , and Happy new year,
now I change all my way I depended on sqlite for handle my data and do what do you said and exactly what you wrote in documentation but I'm facing also issues , there is a wrong in my code but I don't know what is it !

main.dart

void headlessTask(bg.HeadlessEvent headlessEvent) async {
  print('[BackgroundGeolocation HeadlessTask]: $headlessEvent');
  // Implement a 'case' for only those events you're interested in.
  switch(headlessEvent.name) {
    case bg.Event.LOCATION:
      bg.Location location = headlessEvent.event;
      await LocationListenerHelper.onLocation(location);
      print('- Location: $location');
      break;
    case bg.Event.MOTIONCHANGE:
      bg.Location location = headlessEvent.event;
      await LocationListenerHelper.onLocation(location);
      print('- Location: $location');
      break;
  }
}

void main() async {
  runApp( MyApp());
  // Register your headlessTask:
  bg.BackgroundGeolocation.registerHeadlessTask(headlessTask); 
}

home.dart

void initState() {
    /* for run those helpers after draw done */
    Future.delayed(Duration.zero).then(
      (_) {
      // /*
      //   open and init Sqlite Database
      // */
      // SqLiteHelper().databaseInitAndOpen();

        /* 
      init Dynamic Link and listen if there any 
      dynamic link recived */
      DynamicLinkHelper(context).initListen();

        /*
      init Firebase Cloud Messaging 
      and create Listener for any callback if user click or 
      when app in background or terminated */
      FCMHelper(context).init();

        /* 
      Local Notification init & Configration Listener For 
      any notification click call back */
      LocalNotificationsHelper().init(context);
  
        /* 
      Geo Location Listener that will listen for location and 
      check lists and items locations and notification user if
      he's near from any of them */
      LocationListenerHelper(distanceListener: 20).init();

      },
    );
    super.initState();
  }

onLocation helper


  Future<void> init() async {
    // if battery_save_power_mode is on I stop listen
    bool batterSavePowerMode =
        await LocalStorageHelper.getByKey('battery_save_power_mode');

    if (batterSavePowerMode != true) {
      // Fired whenever a location is recorded
      bg.BackgroundGeolocation.onLocation(onLocation, _onLocationError);
      print('[Background location init]');
      //BackGround Geoloacation init
      bg.State state = await bg.BackgroundGeolocation.ready(bg.Config(
        desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
        distanceFilter: distanceListener,
        stopOnTerminate: false,
        startOnBoot: true,
        enableHeadless: true,
        debug: true,
        logLevel: bg.Config.LOG_LEVEL_OFF,
      ));
      print('state.enabled ${state.enabled}');
      if (!state.enabled) bg.BackgroundGeolocation.start();
    }
  }


/*
    Check current Location and lists and items's location and if user
    near by any one of them I push notification
   */
  static Future<void> onLocation(bg.Location location) async {

    List<Map<String, dynamic>> objects = await 
    SqLiteHelper.query(table:'itemslocations');

    if (objects == null || objects.length == 0) {return;}

    print('[new Location listen] ....');
    //? latLng of current location
    LatLng currentLatlng =
        LatLng(location.coords.latitude, location.coords.longitude);
    
     ///// handle the locations data here

}

the error is

E/flutter (16295): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)

I recored my test maybe there is something weird I'm wrong with.
https://youtu.be/zuA4BmTjt8w

@niypoo
Copy link
Author

niypoo commented Dec 27, 2019

I'm trying also remove my own headless task handle and depended on your package handle it's work also when app is opening but after terminated it i hear the debug sound but my app doesn't live don't give me any notification like when he open

@christocracy
Copy link
Member

It makes me angry when people flood the thread with logs. I’m not looking at any of that or anything else in this thread until you clean that up.

@niypoo
Copy link
Author

niypoo commented Dec 27, 2019

any handle code by me inside
Future<void> headlessTask(bg.HeadlessEvent headlessEvent) async {
doesn't work any code even SharedPreferences
SharedPreferences localStorage = await SharedPreferences.getInstance(); return localStorage.get(key);

it's give me

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)

@christocracy
Copy link
Member

Have you Upgraded your Flutter Android Project?

@niypoo
Copy link
Author

niypoo commented Dec 27, 2019

no , i didn't upgrade yet !

@christocracy
Copy link
Member

I strongly suggest you do so. Flutter has completely refactored their "headless" mechanism. You no longer need to do any extra steps in a custom Application java class any more. It's all automatic, but you must upgrade to new api. Follow the directions in the link above.

@niypoo
Copy link
Author

niypoo commented Dec 28, 2019

I did it but now all issues that occurred when background_featch happened when app lunch I check every dependences now and after make app work as expected I will test your package point , sorry for any abuse

@niypoo
Copy link
Author

niypoo commented Dec 29, 2019

I'm facing a same issue background don't hear after terminated app
my AndroidMinfest.xml

I have used android:name=".MainActivity" instead android:name="io.flutter.embedding.android.FlutterActivity" to avoid google_maps unregister issue .

<application
        tools:replace="android:label"
        android:label="myapp" ...... > ....
      <activity
            android:name=".MainActivity"
            android:theme="@style/LaunchTheme" .....

MainActivity.kt is
package codes.nudge.pow

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine);
    }
}

my main.dart


Future<void> headlessTask(bg.HeadlessEvent headlessEvent) async {
  print('--==-=----=-=-=-=-=-=--[BackgroundGeolocation HeadlessTask]: $headlessEvent');
  switch(headlessEvent.name) {
    case bg.Event.LOCATION:
      bg.Location location = headlessEvent.event;  
      print('- Location: $location');
      await LocationListenerHelper.onLocation(location);
      break;
    case bg.Event.MOTIONCHANGE:
      bg.Location location = headlessEvent.event;
      print('- Location: $location');
      await LocationListenerHelper.onLocation(location);
      break;
  }
}

void main() async {
  runApp(LocalizedApp(delegate, MyApp()));

  // Register your headlessTask:
  bg.BackgroundGeolocation.registerHeadlessTask(headlessTask);
  
}

my flutter --version

Flutter 1.12.13+hotfix.5 • channel stable • https://github.com/flutter/flutter.git Framework • revision 27321ebbad (3 weeks ago) • 2019-12-10 18:15:01 -0800 Engine • revision 2994f7e1e6 Tools • Dart 2.7.0

when app is opened it's receives and handle very well but after app terminated not receives any background calls

@niypoo
Copy link
Author

niypoo commented Dec 29, 2019

final I have received background call after create new project only with java and move my code to new project but I can't access on any package like sqflite or SharedPreferences

sqflite gives me

[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: NoSuchMethodError: The method 'query' was called on null.

and when try open database before query to ensure the database is not null gives

Unhandled Exception: MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)

SharedPreferences gives me

Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)

@christocracy
Copy link
Member

christocracy commented Dec 29, 2019

Could you please generate a simple hello-world project and share the github repo with me.

@niypoo
Copy link
Author

niypoo commented Dec 29, 2019

I create new app just with your package and it's working as good , so I think this issue is conflict with other package so i have added one by one and I think I have figure out what package is make this issue that called
"google_places_picker: ^2.0.2+2"

this is a project link in github please check it due to I can't test backend fetch as good as I think
https://github.com/niypoo/headless_test.git

@niypoo
Copy link
Author

niypoo commented Dec 30, 2019

is there any way to handle data from sqflite not SharedPreferences, sqflite not work in backend fetch.

@stale
Copy link

stale bot commented Feb 28, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You may also mark this issue as a "discussion" and I will leave this open.

@stale stale bot added the stale label Feb 28, 2020
@stale
Copy link

stale bot commented Mar 6, 2020

Closing this issue after a prolonged period of inactivity. Fell free to reopen this issue, if this still affecting you.

@stale stale bot closed this as completed Mar 6, 2020
@aweiand
Copy link

aweiand commented Apr 29, 2020

Hi people!
You'l find an answer for the problem? I'm have the same problem. Don't save to sqflite in background...

@Vish88781
Copy link

Vish88781 commented Aug 20, 2022

transistorsoft/flutter_background_fetch#283
Hope this will solve your Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences) @niypoo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants