3

I am using flutter_background_geolocation library to fetch location change event in flutter app. Location service is working perfect in while app is in foreground mode and background mode, but it is not working while app is terminated. Please let me know if there is any mistake in my code.

geolocation_task.dart

import 'dart:convert';
import 'dart:math' show cos, sqrt, asin;
import 'package:flutter/material.dart';
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart'
    as bg;
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart';
import 'config/transistor_auth.dart';
import 'constants/constants.dart';
import 'local_notifications.dart';
import 'model/location_reminder.dart';

Future initPlatform({@required token}) async {
  await configureBackgroundGeolocation(token: token);
}

void registerHeadLessTasks() {
  registerErrorHandler();

  bg.BackgroundGeolocation.registerHeadlessTask(
    backgroundGeolocationHeadlessTask,
  );
}

Future backgroundGeolocationHeadlessTask(bg.HeadlessEvent headlessEvent) async {
  final Location currentLocation =
      await bg.BackgroundGeolocation.getCurrentPosition(samples: 1);
  _onLocation(currentLocation);
  switch (headlessEvent.name) {
    case bg.Event.GEOFENCE:
      final bg.GeofenceEvent geofenceEvent = headlessEvent.event;
      logger.d('Local $geofenceEvent');
      break;
    case bg.Event.GEOFENCESCHANGE:
      final bg.GeofencesChangeEvent event = headlessEvent.event;
      logger.d(event);
      break;
    case bg.Event.SCHEDULE:
      final bg.State state = headlessEvent.event;
      logger.d(state);
      break;
  }
}

Future<TransistorAuthorizationToken> registerApp() async {
  await TransistorAuthorizationToken.destroy(trackerHost);
  final TransistorAuthorizationToken token =
      await bg.TransistorAuthorizationToken.findOrCreate(
          'test', 'test', trackerHost);

  bg.BackgroundGeolocation.setConfig(
      bg.Config(transistorAuthorizationToken: token));

  return token;
}

Future configureBackgroundGeolocation({@required token}) async {
  bg.BackgroundGeolocation.onLocation(_onLocation);
  await bg.BackgroundGeolocation.ready(
    bg.Config(
      transistorAuthorizationToken: token,
      reset: true,
      debug: false,
      logLevel: bg.Config.LOG_LEVEL_VERBOSE,
      desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH,
      distanceFilter: 10.0,
      autoSync: true,
      stopOnTerminate: false,
      foregroundService: true,
      startOnBoot: true,
      enableHeadless: true,
      heartbeatInterval: 60,
      isMoving: false,
    ),
  ).then((bg.State state) async {
    logger.d('[ready] ${state.toMap()}');
    bg.BackgroundGeolocation.start();
  }).catchError((error) {
    logger.e('[ready] ERROR: $error');
  });
}

dynamic _onLocation(bg.Location location) async {
  // Send local notification on location change
  await displayPush(
                title: reminder.title,
                body: reminder.notes,
                payload: jsonEncode(payload));
}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.k8sllc.securehome">

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.VIBRATE" />

<application
    tools:replace="android:label"    
    android:name=".BaseApp"
    android:icon="@mipmap/ic_launcher"
    android:usesCleartextTraffic="true"
    android:label="Lok">
    <activity
        android:name=".MainActivity"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
        android:hardwareAccelerated="true"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:windowSoftInputMode="adjustResize">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="FLUTTER_NOTIFICATION_CLICK" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

        <meta-data
            android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
            android:value="true" />
        <meta-data
            android:name="firebase_crashlytics_collection_enabled"
            android:value="true" />
    </activity>
    <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>

    <activity
        android:name="com.yalantis.ucrop.UCropActivity"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" />

    <meta-data
        android:name="com.facebook.sdk.ApplicationId"
        android:value="@string/facebook_app_id" />
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="test_key” />

    <meta-data
        android:name="com.transistorsoft.locationmanager.license"
        android:value="test_key" />

    <meta-data
        android:name="com.transistorsoft.locationmanager.ENCRYPTION_PASSWORD"
        android:value="test_pass” />

    <service
        android:name="com.transistorsoft.locationmanager.service.TrackingService"
        android:foregroundServiceType="location"/>
    <service
        android:name="com.transistorsoft.locationmanager.service.LocationRequestService"
        android:foregroundServiceType="location"/>

    <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
        </intent-filter>
    </receiver>

    <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
    
    <!-- Add this content for push notification -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="Lok" />
    <service android:name=".FireBaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service android:name=".FireBaseInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>    

</application>

android/build.gradle

buildscript {
repositories {
    google()
    jcenter()
    mavenCentral()
    maven { url 'https://maven.fabric.io/public' }
}

dependencies {
    classpath 'com.android.tools.build:gradle:3.6.4'
    classpath 'com.google.gms:google-services:4.3.3'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72"
    classpath 'io.fabric.tools:gradle:1.+'
}
}

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            // [required] flutter_background_geolocation
            url "${project(':flutter_background_geolocation').projectDir}/libs"
        }
        maven {
            // [required] background_fetch
            url "${project(':background_fetch').projectDir}/libs"
        }
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

apply plugin: 'com.google.gms.google-services'

Flutter doctor summary

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.17.4, on Mac OS X 10.15.5 19F101, locale en-GB)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.6)
[✓] Android Studio (version 4.0)
[✓] VS Code (version 1.48.0)
[✓] Connected device (1 available)

• No issues found!

0 Answers0