Flutter seems to have a problem with 3rd-party Android libraries which merge their own AndroidManifest.xml
into the application, particularly the android:label
attribute.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
package="com.example.helloworld">
<application
+ tools:replace="android:label"
android:name="io.flutter.app.FlutterApplication"
android:label="flutter_background_geolocation_example"
android:icon="@mipmap/ic_launcher">
</manifest>
Warning
Failure to perform the step above will result in a build error: Manifest merger failed
Note
At the root of your /android
folder, your Flutter app will contain one of the following files:
build.gradle
build.gradle.kts
(new Kotlin-based version)
Add the following required maven
repo url to whichever file your app has:
If your app contains an android/build.gradle
:
+ext {
+ appCompatVersion = "1.4.2" // or higher / as desired
+ playServicesLocationVersion = "21.3.0" // or higher / as desired
+}
allprojects { // <-- IMPORTANT: allprojects
repositories {
google()
mavenCentral()
+ // [required] flutter_background_geolocation
+ maven { url "${project(':flutter_background_geolocation').projectDir}/libs" }
+ maven { url 'https://developer.huawei.com/repo/' }
+ // [required] background_fetch
+ maven { url "${project(':background_fetch').projectDir}/libs" }
}
}
OR if your app contains an android/build.gradle.kts
:
allprojects {
+ ext {
+ set("appCompatVersion", "1.4.2") // or higher / as desired
+ set("playServicesLocationVersion", "21.3.0") // or higher / as desired
+ }
repositories {
google()
mavenCentral()
+ // [required] background_geolocation
+ maven(url = "${project(":flutter_background_geolocation").projectDir}/libs")
+ maven(url = "https://developer.huawei.com/repo/")
+ // [required] background_fetch
+ maven(url = "${project(":background_fetch").projectDir}/libs")
}
}
If your app contains an android/app/build.gradle
:
// flutter_background_geolocation
+Project background_geolocation = project(':flutter_background_geolocation')
+apply from: "${background_geolocation.projectDir}/background_geolocation.gradle"
android {
.
.
.
buildTypes {
release {
.
.
.
minifyEnabled true
+ shrinkResources false // <-- REQUIRED !!!
}
}
}
OR if your app contains an android/app/build.gradle.kts
:
+val backgroundGeolocation = project(":flutter_background_geolocation")
+apply { from("${backgroundGeolocation.projectDir}/background_geolocation.gradle") }
android {
.
.
.
buildTypes {
release {
.
.
.
isMinifyEnabled = true
+ isShrinkResources = false // <-- REQUIRED !!!
}
}
}
If you've not yet purchased a license to unlock Android, you can purchase one here. Otherwise, ignore this step (Android is fully functional in DEBUG builds without a license key so you can evaluate the plugin).
-
Login to Customer Dashboard to generate an application key:
-
Add your license-key to
android/app/src/main/AndroidManifest.xml
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.your.package.id">
<application>
<!-- flutter_background_geolocation licence -->
+ <meta-data android:name="com.transistorsoft.locationmanager.license" android:value="YOUR_LICENCE_KEY_HERE" />
.
.
.
</application>
</manifest>
If you've purchased an HMS Background Geolocation License for installing the plugin on Huawei devices without Google Play Services installed, add your HMS Background Geolocation license key:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.your.package.id">
<application>
<!-- flutter_background_geolocation licence -->
<meta-data android:name="com.transistorsoft.locationmanager.license" android:value="YOUR_LICENCE_KEY_HERE" />
<!-- HMS Background Geolocation licence -->
+ <meta-data android:name="com.transistorsoft.locationmanager.hms.license" android:value="YOUR_HMS_LICENCE_KEY_HERE" />
.
.
.
</application>
</manifest>
Warning
Huawei HMS support requires flutter_background_geolocation >= 3.10.0
.
If you've purchased a license for the Polygon Geofencing add-on, add the following license key to your AndroidManifest
(Polygon Geofencing is fully functional in DEBUG builds so you can try before you buy):
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.your.package.id">
<application>
<!-- flutter_background_geolocation licence -->
<meta-data android:name="com.transistorsoft.locationmanager.license" android:value="YOUR_LICENCE_KEY_HERE" />
<!-- Background Geolocation Polygon Geofencing Licence -->
+ <meta-data android:name="com.transistorsoft.locationmanager.polygon.license" android:value="YOUR_POLYGON_LICENCE_KEY_HERE" />
.
.
.
</application>
</manifest>
The plugin uses AlarmManager
"exact alarms" for precise scheduling of events (eg: Config.stopTimeout
, Config.motionTriggerDelay
, Config.schedule
). Android 14 (SDK 34), has restricted usage of "AlarmManager
exact alarms". To continue using precise timing of events with Android 14, you can manually add this permission to your AndroidManifest
. Otherwise, the plugin will gracefully fall-back to "in-exact AlarmManager
scheduling". For more information about Android's AlarmManager
, see the Android API Docs.
📂 In your AndroidManifest
, add the following permission (exactly as-shown):
<manifest>
<uses-permission android:minSdkVersion="34" android:name="android.permission.USE_EXACT_ALARM" />
.
.
.
</manifest>
Warning
It has been announced that Google Play Store has plans to impose greater scrutiny over usage of this permission (which is why the plugin does not automatically add it).
If you intend to respond to the BackgroundGeolocation SDK's events with your own dart
callback while your app is terminated, that is Headless, See Android Headless Mode and perform those additional steps now.
BackgroundGeolocation.ready(Config(
enableHeadless: true // <--
));
flutter_background_geolocation
installs a dependency background_fetch
(also created by Transistor Software). You can optionally perform the Android Setup for it as well.
Tip
background_fetch
is helpful for executing a periodic task (eg: every 15 minutes). You could use background_fetch
to periodically request the current location:
// Execute a task about every 15 minutes:
BackgroundFetch.configure(BackgroundFetchConfig(
minimumFetchInterval: 15
), (String taskId) async { // <-- This is your periodic-task callback
var location = await BackgroundGeolocation.getCurrentPosition(
samples: 3,
extras: { // <-- your own arbitrary meta-data
"event": "getCurrentPosition"
}
);
print('[getCurrentPosition] $location');
BackgroundFetch.finish(taskId); // <-- signal that your task is complete
})