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!