Closed wemersonrv closed 4 years ago
Look like your callback isn't static, try to create a static function like https://github.com/rekab-app/background_locator/blob/e165b784d1ed672e11b2717c81b0bcfa2fbd122b/example/lib/main.dart#L94-L99
Sorry my bad, it is static... i just copy and paste it here on same code of registerLocationUpdate
to make more short... but here it's static... The difference is that i'm not uising setLog
static void callback(LocationDto locationDto) async {
print('location in dart: ${locationDto.toString()}');
final SendPort send = IsolateNameServer.lookupPortByName(_isolateName);
send?.send(locationDto);
}
Looking at topic 3 on Android item on documentation: 3. If you need to call other plugins, even when the application is terminated, create the Application.kt file and add the necessary plugins to the registerWith function.
I'm calling calling a function in another file, not in same file, and using shared prefs to store locations, and it has other plugins that i need. In that case i need to register all imported plugins on `Application.kt?
Look at imports:
lib/main.dart
port.listen(
(dynamic data) async {
// await updateUI(data);
await locationBackground.updateHomeTime(data);
},
);
lib/uteis/locator.dart
import 'dart:async';
import 'dart:isolate';
import 'dart:ui';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:geodesy/geodesy.dart';
import 'package:background_locator/location_dto.dart';
import 'package:geohash/geohash.dart';
import 'package:geoflutterfire/geoflutterfire.dart';
import './constants.dart';
import './location_model.dart';
import './uteis.dart';
class Locator{
Uteis uteis = new Uteis();
ReceivePort port = ReceivePort();
static final _isolateName = 'LocatorIsolate';
bool isRunning = true;
static void callback(LocationDto locationDto) async {
print('location in dart: ${locationDto.toString()}');
final SendPort send = IsolateNameServer.lookupPortByName(_isolateName);
send?.send(locationDto);
}
static void notificationCallback() {
print('Background Location notificationCallback');
}
// Here is when i save the loction in shared prefs
Future<void> updateHomeTime(LocationDto data) async {
DateTime now = DateTime.now();
List<LocationModel> locations = await uteis.getLocations();
locations.add(LocationModel.fromGelocation(userPoint['email'], now, data));
await uteis.storeLocations(locations);
// TODO: Persist these locations on shared prefs to firebase firestore
}
I am storing locations on shared prefs to send then to firebase firestore later...
Basically you have two part on your app, Flutter and the plugins's service
Two are in separate Isolate so they don't share no memory whatsoever, the only way of comunication is through port
on BackgroundLocator.registerLocationUpdate
you pass to the plugin the callback and the notification callback (which is useless in your case and will be optional in the future), so the plugin will execute the callback at every new location every x seconds of interval you specified.
This happen in background and without the need of Flutter so the only way to change UI element is by listening through the port and do changes here.
In your case you execute what should be in callback, inside port.listen. If Flutter is killed you can't listen to anything, only the plugin Isolate will be running calling callback
.
On topic 3 like you said you need to import the plugin you want to use inside the kotlin file (its path_provider on the example) so this way you can use this plugin inside the callback (Basically when you download through pub get
they are auto imported insideandroid/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
, which MainActivity.kt will configureFlutterEngine
using theses. On Application.kt you do the same except that you don't import them all)
Take a look here https://github.com/rekab-app/background_locator/pull/27 you will maybe better understand (also check the example)
in Android
I want to send location and another data (eg.SharedPreferences data , battery_level) to my server in background process. It works well in port.listen function.
When I kill process port.listen not working but callback still work.
I move code from port.listen function to callback function. There was some problem . callback function is a static function therefore it can't access instance data or object (eg.SharedPreferences data , battery_level)
Can I pass some parameter to callback function or you have any idea for my situation?
I think you don't have imported the kotlin part of the two plugins so you get NotImplementedError
is there any way to stop the callback when the application is killed? I am getting the same behaviors as @oocokeoo and the notification is shown even if the app killed (without running port.listen) ,,,, but I just want to run some code in port.listen while my app in the background (not when it is killed). So I just want to remove the notification and callback when the application is killed.
Then you can set autoStop
to true
@RomanJos According to the ReadMe > [autoStop] If true locator will stop as soon as app goes to background.
I have set [autoStop] to true, but once my application goes to background (without killing it), the callback stop and the notification disappear. So, unfortunately, i am still not able to achieve what I am looking for.
Oh my bad I read too fast lol I think that you can achieve this by following this post https://medium.com/pharos-production/flutter-app-lifecycle-4b0ab4a4211a basically when the app is paused you stop the locator service and re-start it when the app get resumed Its a little hacky since you use a sticky service in background to get the location only when the app is opened. Using a timer that get the location with another plugins will maybe be better idk
Finally, I found a workaround. I think many users of this plugin looking for this use case. Just receiving locations data when the application in the background or foreground. Then kill the services once the application has been killed by the user (force kill, swipe it from the recent application).
I achieved that by editing the 2 services from background_locator in my androidManifest.xml:
android:stopWithTask="true"
<service android:name="rekab.app.background_locator.LocatorService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true" android:stopWithTask="true"/> <service android:name="rekab.app.background_locator.IsolateHolderService" android:permission="android.permission.FOREGROUND_SERVICE" android:exported="true" android:stopWithTask="true" />
This is actually really clever, I don't know how android's manifest work actually I will add it in the readme
I think I have to take more time reading the issue, I don't know why I came up with lifecycle lol anyway
Basically you have two part on your app, Flutter and the plugins's service Two are in separate Isolate so they don't share no memory whatsoever, the only way of comunication is through port on
BackgroundLocator.registerLocationUpdate
you pass to the plugin the callback and the notification callback (which is useless in your case and will be optional in the future), so the plugin will execute the callback at every new location every x seconds of interval you specified. This happen in background and without the need of Flutter so the only way to change UI element is by listening through the port and do changes here. In your case you execute what should be in callback, inside port.listen. If Flutter is killed you can't listen to anything, only the plugin Isolate will be running callingcallback
.On topic 3 like you said you need to import the plugin you want to use inside the kotlin file (its path_provider on the example) so this way you can use this plugin inside the callback (Basically when you download through
pub get
they are auto imported insideandroid/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
, which MainActivity.kt willconfigureFlutterEngine
using theses. On Application.kt you do the same except that you don't import them all)Take a look here #27 you will maybe better understand (also check the example)
Hi, make the Application.kt
file as oriented:
package br.com.myapp
import rekab.app.background_locator.LocatorService
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.pathprovider.PathProviderPlugin
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
LocatorService.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.pathprovider")) {
PathProviderPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.pathprovider"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin")) {
CloudFirestorePlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.firebaseauth.FirebaseAuthPlugin'")) {
FirebaseAuthPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebaseauth.FirebaseAuthPlugin'"))
}
if (!registry!!.hasPlugin("com.baseflow.location_permissions.LocationPermissionsPlugin'")) {
LocationPermissionsPlugin.registerWith(registry!!.registrarFor("com.baseflow.location_permissions.LocationPermissionsPlugin'"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.sharedpreferences'")) {
SharedPreferencesPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.sharedpreferences'"))
}
}
}
There are a couple of plugins that are installed and i use them on app but are not registered in android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
:
Is this a proble?
If they are not in GeneratedPluginRegistrant.java
that mean they don't have any android natives calls or specific android codes, for example generating UUID will just generate random string so you don't make any native calls where path_provider ask android the path of DocumensDirectory etc
If they are not in
GeneratedPluginRegistrant.java
that mean they don't have any android natives calls or specific android codes, for example generating UUID will just generate random string so you don't make any native calls where path_provider ask android the path of DocumensDirectory etc
Ok, understand. Making a build now, with Application.kt
i posted before and it giving me the error:
D:\DadosImportantes\dev\Projetos\WemersonRV\test_background\android\app\src\main\kotlin\br\com\myapp\Application.kt: (21, 13): Unresolved reference: CloudFirestorePlugin e: D:\DadosImportantes\dev\Projetos\WemersonRV\test_background\android\app\src\main\kotlin\br\com\myapp\Application.kt: (24, 13): Unresolved reference: FirebaseAuthPlugin e: D:\DadosImportantes\dev\Projetos\WemersonRV\test_background\android\app\src\main\kotlin\br\com\myapp\Application.kt: (27, 13): Unresolved reference: LocationPermissionsPlugin e: D:\DadosImportantes\dev\Projetos\WemersonRV\test_background\android\app\src\main\kotlin\br\com\myapp\Application.kt: (30, 13): Unresolved reference: SharedPreferencesPlugin
FAILURE: Build failed with an exception.
- What went wrong: Execution failed for task ':app:compileReleaseKotlin'.
My kotlin version in android/build.gradle
is 1.3.50. Need a specific version?
So i change the kotlin file using the fixes you post in PR #27 but the error persist. See below the Application.kt
final file:
package br.com.myapp
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.pathprovider.PathProviderPlugin
import io.flutter.view.FlutterMain
import rekab.app.background_locator.LocatorService
class LocationService : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
LocatorService.setPluginRegistrant(this)
FlutterMain.startInitialization(this)
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.pathprovider")) {
PathProviderPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.pathprovider"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin")) {
CloudFirestorePlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.firebaseauth.FirebaseAuthPlugin'")) {
FirebaseAuthPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebaseauth.FirebaseAuthPlugin'"))
}
if (!registry!!.hasPlugin("com.baseflow.location_permissions.LocationPermissionsPlugin'")) {
LocationPermissionsPlugin.registerWith(registry!!.registrarFor("com.baseflow.location_permissions.LocationPermissionsPlugin'"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.sharedpreferences'")) {
SharedPreferencesPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.sharedpreferences'"))
}
}
}
See the registered plugins on android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
. All plugins referenced on Application.kt
are referenced:
You can't do CloudFirestorePlugin.registerWith
if you don't import it before :
import io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin
import io.flutter.plugins.firebaseauth.FirebaseAuthPlugin
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin
I don't think its a good idea to have permisison handler checking every callback but rather before launching the plugin
Ok, understand. Making a build now, with
Application.kt
i posted before and it giving me the error:
I just have to ask, do you have this plugins in your podspec.yaml
?
I just added your listed plugins to my podspec.yaml
and registered them without any problem.
And as @RomanJos said, you have to import the plugins first.
@RomanJos
You can't do
CloudFirestorePlugin.registerWith
if you don't import it before :import io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin import io.flutter.plugins.firebaseauth.FirebaseAuthPlugin import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin
It's imported on my
main.dart
file.I don't think its a good idea to have permisison handler checking every callback but rather before launching the plugin
OK, understand... It makes perfect sense, since the permission should have been resolved when you first started the app. Will remove this plugin,
@mehdok
Ok, understand. Making a build now, with
Application.kt
i posted before and it giving me the error:I just have to ask, do you have this plugins in your
podspec.yaml
? I just added your listed plugins to mypodspec.yaml
and registered them without any problem. And as @RomanJos said, you have to import the plugins first. Yep, i have. Plugin works sooo fine! Amazing plugin. But if i close the app, not works.
My challenge is to make it work when user closes the app, so i need to persist data to firestore and if there is no internet connection, store it in shared prefs first.
I think i understand it now. I need to import the plugins in Application.kt
before register them.
The documentation shows the import, but i just go to register area and forgot the imports.
Yeah exactly you need to import them in your kotlin files before calling their registerWith
I just put the example as it is on the readme but it need to be more clear with more example, only one things that I don't understand is
if (!registry!!.hasPlugin("io.flutter.plugins.pathprovider")) {
PathProviderPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.pathprovider"))
}
Here we check if registry (that shouldn't be null) don't have the plugin "io.flutter.plugins.pathprovider" to register it but why do we check it and don't just register it ?
And why some plugins like path provider and sharedpreference are like io.flutter.plugins.name.NamePlugin
in import but io.flutter.plugins.name
in hasPlugin()
?
Yeah exactly you need to import them in your kotlin files before calling their
registerWith
I just put the example as it is on the readme but it need to be more clear with more example, only one things that I don't understand isif (!registry!!.hasPlugin("io.flutter.plugins.pathprovider")) { PathProviderPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.pathprovider")) }
Here we check if registry (that shouldn't be null) don't have the plugin "io.flutter.plugins.pathprovider" to register it but why do we check it and don't just register it ? And why some plugins like path provider and sharedpreference are like
io.flutter.plugins.name.NamePlugin
in import butio.flutter.plugins.name
inhasPlugin()
?
Man, my bad... i think i understand it now... Below my last try... every plugin, has a commented line showing how it is listed on android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java
package br.com.myapp
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.pathprovider.PathProviderPlugin
import io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin
import io.flutter.plugins.firebaseauth.FirebaseAuthPlugin
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin
import io.flutter.view.FlutterMain
import rekab.app.background_locator.LocatorService
class LocationService : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
LocatorService.setPluginRegistrant(this)
FlutterMain.startInitialization(this)
}
override fun registerWith(registry: PluginRegistry?) {
// flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
if (!registry!!.hasPlugin("io.flutter.plugins.pathprovider")) {
PathProviderPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.pathprovider"))
}
// io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin.registerWith(shimPluginRegistry.registrarFor("io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin"));
if (!registry!!.hasPlugin("io.flutter.plugins.firebase.cloudfirestore")) {
CloudFirestorePlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebase.cloudfirestore"))
}
// io.flutter.plugins.firebaseauth.FirebaseAuthPlugin.registerWith(shimPluginRegistry.registrarFor("io.flutter.plugins.firebaseauth.FirebaseAuthPlugin"));
if (!registry!!.hasPlugin("io.flutter.plugins.firebaseauth")) {
FirebaseAuthPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebaseauth"))
}
// flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
if (!registry!!.hasPlugin("io.flutter.plugins.sharedpreferences")) {
SharedPreferencesPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.sharedpreferences"))
}
}
}
Oh yeah but I forgot to tell that my last two question wasn't specifically for you I mean I didn't do this part of the readme and I don't know nothing about kotlin lol but if its working now thats perfect then
Oh yeah but I forgot to tell that my last two question wasn't specifically for you I mean I didn't do this part of the readme and I don't know nothing about kotlin lol but if its working now thats perfect then
Ok. Understand.
Well. Make a release now. App crash when start at first time.
App crash when start at first time.
Oh, I though it worked :( then I don't know, I tried myself with your example https://github.com/rekab-app/background_locator/issues/30#issuecomment-610144172 with adding the tree import I said after and it didn't crashed on start Maybe its when you use those plugins that it fail then I will be no help for you
Nope. don't working. App crash when start.
See below: Removed all plugins, and copy and paste documentation example. Just change the app package:
package br.com.myapp
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.pathprovider.PathProviderPlugin
import io.flutter.view.FlutterMain
import rekab.app.background_locator.LocatorService
class LocationService : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
LocatorService.setPluginRegistrant(this)
FlutterMain.startInitialization(this)
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.pathprovider")) {
PathProviderPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.pathprovider"))
}
}
}
<application
android:name="br.com.myapp"
android:label="My App"
android:icon="@mipmap/ic_launcher">
But when i remove the Application.kt
and change back
android:name` on AndroidManifest.xml app works...
Ohh you forgot to add LocationService
in android:name
like android:name="br.com.myapp.LocationService"
Ohh you forgot to add
LocationService
inandroid:name
likeandroid:name="br.com.myapp.LocationService"
Yeah, right!
Changed now. App builds and run without conflict.
What i expect: Store locations to shared preferences with 6 minutes interval, whether the application is open or closed. After store in shared prefs, is internet is available; persist them to firestore too
Below a report about what is working and what's not:
In short. Is working as before. When app is opened it works. but not when closes app. When open app, works fine again and capture every 6 minutes.
android/app/src/main/kotlink/br.copm/myapp/LocationService.kt
package br.com.myapp
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.pathprovider.PathProviderPlugin
import io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin
import io.flutter.plugins.firebaseauth.FirebaseAuthPlugin
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin
import io.flutter.view.FlutterMain
import rekab.app.background_locator.LocatorService
class LocationService : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
LocatorService.setPluginRegistrant(this)
FlutterMain.startInitialization(this)
}
override fun registerWith(registry: PluginRegistry?) {
if (!registry!!.hasPlugin("io.flutter.plugins.pathprovider")) {
PathProviderPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.pathprovider"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.firebase.cloudfirestore")) {
CloudFirestorePlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebase.cloudfirestore"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.firebaseauth")) {
FirebaseAuthPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.firebaseauth"))
}
if (!registry!!.hasPlugin("io.flutter.plugins.sharedpreferences")) {
SharedPreferencesPlugin.registerWith(registry!!.registrarFor("io.flutter.plugins.sharedpreferences"))
}
}
}
android/app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="br.com.myapp">
<!-- App permissions -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Background Locator permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="br.com.myapp.LocationService"
android:label="My App"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Facebook Login configuration -->
<meta-data android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<!-- Background Locator configuration -->
<receiver
android:name="rekab.app.background_locator.LocatorBroadcastReceiver"
android:enabled="true"
android:exported="true"
/>
<service
android:name="rekab.app.background_locator.LocatorService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"
/>
<service
android:name="rekab.app.background_locator.IsolateHolderService"
android:permission="android.permission.FOREGROUND_SERVICE"
android:exported="true"
/>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
BackgroundLocator.registerLocationUpdate(
LocationBackground.callback,
androidNotificationCallback: LocationBackground.notificationCallback,
settings: LocationSettings(
notificationTitle: "My App",
notificationMsg: "My Notification text",
wakeLockTime: 20,
autoStop: false,
interval: 360, // 6 minutes
),
);
static void callback(LocationDto locationDto) async {
print('location in dart: ${locationDto.toString()}');
final SendPort send = IsolateNameServer.lookupPortByName(_isolateName);
send?.send(locationDto);
}
static void notificationCallback() {
print('Background Location notificationCallback');
}
You need to put every background operation like writing in a file, send to internet the location etc inside the callback
function and every UI operation inside the port.listen
From your example it look like you only send the new location to the port in your callback function, so if Flutter get killed (like removing the app from the recent app list for example) nothing will listen to.
Also this is why we have these lines on startup https://github.com/rekab-app/background_locator/blob/02c71fa2372c03b5c33974930b9c88400993cab4/example/lib/main.dart#L34-L38
This way we remove the old port that was created from the previous Flutter Activity and assign the new one.
Don't hesitate to look at the example :
https://github.com/rekab-app/background_locator/blob/master/example/lib/main.dart
Hello, Now i understand! It works here. It works in a 6 minutes interval, exactly as i configured.
The unique issue is when it works with opened app, store both; from UI and from Background and i need just one!
Can i disable the ports right?
Just remove port variable declaration and port.listen? Is there more lines to remove?
// ReceivePort port = ReceivePort();
bool isRunning = true;
static final _isolateName = 'LocatorIsolate';
@override
void initState() {
super.initState();
if (IsolateNameServer.lookupPortByName(_isolateName) != null) {
IsolateNameServer.removePortNameMapping(_isolateName);
}
/*
IsolateNameServer.registerPortWithName(port.sendPort, _isolateName);
port.listen(
(dynamic data) async {
await LocationBackground.updateHomeTime(data);
},
onError: (err) {
print("Error log in dart: $err");
},
cancelOnError: false,
);
*/
initPlatformState();
}
Future<void> initPlatformState() async {
await BackgroundLocator.initialize();
final _isRunning = await BackgroundLocator.isRegisterLocationUpdate();
setState(() {
isRunning = _isRunning;
});
}
static void callback(LocationDto locationDto) async {
print('location in dart: ${locationDto.toString()}');
await updateHomeTime(locationDto); // My Function
// final SendPort send = IsolateNameServer.lookupPortByName(_isolateName);
// send?.send(locationDto);
}
If you don't need UI update then remove the port. There should be no problem.
I'm closing this issue Because I think it's more like stackoverflow question.
Feel free to open it.
Yeah port.listen
get called only when Flutter is alive where the callback keep getting called by the plugin which is a service so it never die
and you can remove this too :
if (IsolateNameServer.lookupPortByName(_isolateName) != null) {
IsolateNameServer.removePortNameMapping(_isolateName);
}
it's more like stackoverflow question.
I don't think Stackoverflow is used for Flutter libraries lol
Hello.
Testing in Android, plugin works fine, but have an issue: When close app, the notification baloon still shows on device; but stop capturing. There is some extra config to do when close app ?
Settings: