Git Product home page Git Product logo

Comments (31)

ibrahimsoliman97 avatar ibrahimsoliman97 commented on July 18, 2024 4

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" />

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024 1

Then you can set autoStop to true

from background_locator.

mehdok avatar mehdok commented on July 18, 2024 1

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.

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

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...

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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 #27 you will maybe better understand (also check the example)

from background_locator.

oocokeoo avatar oocokeoo commented on July 18, 2024

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?

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

I think you don't have imported the kotlin part of the two plugins so you get NotImplementedError

from background_locator.

ibrahimsoliman97 avatar ibrahimsoliman97 commented on July 18, 2024

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.

from background_locator.

ibrahimsoliman97 avatar ibrahimsoliman97 commented on July 18, 2024

@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.

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

This is actually really clever, I don't know how android's manifest work actually I will add it in the readme

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

I think I have to take more time reading the issue, I don't know why I came up with lifecycle lol anyway

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

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 #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:

  • import 'package:geodesy/geodesy.dart';
  • import 'package:scoped_model/'scoped'_model.dart';
  • import 'package:uuid/uuid.dart';

Is this a proble?

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

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:

image

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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

from background_locator.

mehdok avatar mehdok commented on July 18, 2024

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.

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

@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 my podspec.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.

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

I think i understand it now. I need to import the plugins in Application.kt before register them.

image

The documentation shows the import, but i just go to register area and forgot the imports.

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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() ?

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

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() ?

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"))
        }
    }
}

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

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.

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

App crash when start at first time.

Oh, I though it worked :( then I don't know, I tried myself with your example #30 (comment) 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

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

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...

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

Ohh you forgot to add LocationService in android:name like android:name="br.com.myapp.LocationService"

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

Ohh you forgot to add LocationService in android:name like android: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:

  • [ OK ] Run when app is open, and device is awaked
  • [ OK ] Run when app is open, and device is locked
  • [ FALHA ] Run when app is closed, , and device is awaked
  • [ FALHA ] Run when app is closed, and device is locked

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');
  }

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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

from background_locator.

wemersonrv avatar wemersonrv commented on July 18, 2024

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);
  }

from background_locator.

RomanJos avatar RomanJos commented on July 18, 2024

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

from background_locator.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.