-
Notifications
You must be signed in to change notification settings - Fork 242
Android Custom Notification Layout
The BackgroundGeolocation Android SDK runs as a foreground-service, which requires a persistent notification. If the default notification doesn't suit your needs (eg: you want to add custom buttons), you can design your own notification layout:
📂 app/build.gradle
:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1' // or higher
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' // or higher
+ implementation "androidx.appcompat:appcompat:${rootProject.ext.appCompatVersion}"
}
Open your application in Android Studio. Select File->New->XML->Layout XML file:
Enter any layout name. Your file will be created in the folder app/res/layouts
:
Even if you have no experience with Android Layouts, it doesn't take much to figure out the basics. You'll mostly be adding <TextView />
, <ImageView />
and <Button />
elements. The key thing to be aware of is the android:id
of these elements and how these are referenced from BackgroundGeolocation.notification
configuration: your android:id
must be prefixed with the word notification
(eg: notificationText
). There is one exception: applicationName
, which the plugin will automatically render your Android application name.
When BackgroundGeolocation renders your custom notification layout, it will be querying for the following elements addressed by their android:id
. When found, their content will be updated from the corresponding "Data-source":
Layout element android:id
|
Data-source |
---|---|
applicationName |
Application name from AndroidManifest
|
notificationTitle |
notification.title |
notificationText |
notification.text |
notificationSmallIcon |
notification.smallIcon |
notificationLargeIcon |
notification.largeIcon |
bg.BackgroundGeolocation.ready(bg.Config(
notification: bg.Notification(
layout: "my_notification_layout", // <-- custom layout xml file
title: "The Notification Title",
text: "The Notification Text",
smallIcon: "mipmap/my_small_icon", // <-- defaults to app icon
largeIcon: "mipmap/my_large_icon"
)
));
You can declare your own custom <TextView />
elements and render data into them using the notification.strings
parameter.
<TextView
android:id="@+id/myCustomElement" // <-- myCustomElement
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="notificationTitle" />
You can provide data to your custom elements using the notification.strings
configuration parameter:
bg.BackgroundGeolocation.ready(bg.Config(
notification: bg.Notification(
strings: {
'myCustomElement': 'My Custom Element Text'
}
)
));
You can declare your own custom <Button />
elements and register click-listeners upon them using the notification.actions
parameter:
<Button
android:id="@+id/notificationButtonFoo" // <-- notificationButtonFoo
style="@style/Widget.AppCompat.Button.Small"
android:layout_width="60dp"
android:layout_height="40dp"
android:text="Foo" />
Register listeners for your button using notification.actions
:
bg.BackgroundGeolocation.ready(bg.Config(
notification: bg.Notification(
actions: [ // <-- register button listeners
'notificationButtonFoo',
'notificationButtonBar'
]
)
));
// Listen to custom button clicks:
bg.BackgroundGeolocation.onNotificationAction((buttonId) {
// Listen to custom notification button clicks (notification.actions)
print('[onNotificationAction] - $buttonId');
switch(buttonId) {
case 'notificationButtonFoo':
// Handle button click on [Foo]
break;
case 'notificationButtonBar':
// Handle button click on [Bar]
break;
}
});
As a starting-point for your custom layout, copy the following content into your new file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="135dp"
android:gravity="start"
android:adjustViewBounds="true"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/notificationSmallIcon"
android:layout_width="16dp"
android:layout_height="16dp"
android:tint="@android:color/background_dark"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/applicationName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="10dp"
android:text="applicationName"
android:textAppearance="@style/TextAppearance.Compat.Notification.Title"
android:textColor="#888888"
android:textSize="12sp" />
</LinearLayout>
<TextView
android:id="@+id/notificationTitle"
style="@style/TextAppearance.Compat.Notification.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="notificationTitle"
android:textSize="14sp" />
<TextView
android:id="@+id/notificationText"
style="@style/TextAppearance.Compat.Notification.Line2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="notificationText"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="horizontal">
<Button
android:id="@+id/notificationButtonFoo"
style="@style/Widget.AppCompat.Button.Small"
android:layout_width="60dp"
android:layout_height="40dp"
android:text="FooA" />
<Button
android:id="@+id/notificationButtonBar"
style="@style/Widget.AppCompat.Button.Small"
android:layout_width="60dp"
android:layout_height="40dp"
android:text="Bar" />
</LinearLayout>
</LinearLayout>
bg.BackgroundGeolocation.ready(bg.Config(
notification: bg.Notification(
title: 'The title',
text: 'The text',
layout: 'notification_layout',
actions: [
'notificationButtonFoo', // <-- register button click-listeners
'notificationButtonBar'
],
strings: {
'myCustomTextBox1': 'custom TextBox element'
}
)
));
// Listen to custom notification button clicks (notification.actions)
bg.BackgroundGeolocation.onNotificationAction((buttonId) {
// Listen to custom notification button clicks (notification.actions)
print('[onNotificationAction] - $buttonId');
switch(buttonId) {
case 'notificationButtonFoo':
// Handle button click on [Foo]
break;
case 'notificationButtonBar':
// Handle button click on [Bar]
break;
}
});