diff --git a/gradle/versions.gradle b/gradle/versions.gradle
index 1a8f14d4..a37848a0 100644
--- a/gradle/versions.gradle
+++ b/gradle/versions.gradle
@@ -1,5 +1,5 @@
 ext.versions = [
         minSdk               : 21,
-        targetSdk            : 30,
+        targetSdk            : 31,
         compileSdk           : 31,
 ]
\ No newline at end of file
diff --git a/ultrasonic/src/main/AndroidManifest.xml b/ultrasonic/src/main/AndroidManifest.xml
index 8c3f2dde..d8ed9a5f 100644
--- a/ultrasonic/src/main/AndroidManifest.xml
+++ b/ultrasonic/src/main/AndroidManifest.xml
@@ -21,6 +21,8 @@
 
     <application
         android:allowBackup="false"
+        android:fullBackupContent="@xml/backup_descriptor"
+        android:dataExtractionRules="@xml/backup_rules"
         android:icon="@mipmap/ic_launcher"
         android:roundIcon="@mipmap/ic_launcher_round"
         android:theme="@style/NoActionBar"
@@ -40,7 +42,8 @@
 
         <activity android:name=".activity.NavigationActivity"
             android:configChanges="orientation|keyboardHidden"
-            android:launchMode="singleTask">
+            android:launchMode="singleTask"
+            android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <action android:name="android.intent.action.SEARCH"/>
@@ -61,7 +64,7 @@
             android:exported="false">
         </service>
 
-        <!-- TODO: Check if it works with exported=false as well -->
+        <!-- Needs to be exported: https://android.googlesource.com/platform/developers/build/+/4de32d4/prebuilts/gradle/MediaBrowserService/README.md -->
         <service android:name=".playback.PlaybackService"
             android:label="@string/common.appname"
             android:exported="true">
@@ -150,7 +153,8 @@
         </receiver>
         <provider
             android:name=".provider.SearchSuggestionProvider"
-            android:authorities="org.moire.ultrasonic.provider.SearchSuggestionProvider"/>
+            android:authorities="org.moire.ultrasonic.provider.SearchSuggestionProvider"
+            android:exported="true" />
 
     </application>
 
diff --git a/ultrasonic/src/main/res/xml/backup_descriptor.xml b/ultrasonic/src/main/res/xml/backup_descriptor.xml
new file mode 100644
index 00000000..458ac9da
--- /dev/null
+++ b/ultrasonic/src/main/res/xml/backup_descriptor.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Targeting Android 11 or lower -->
+<full-backup-content>
+    <!-- The following "exclude" elements are not part of the auto backup -->
+    <!--exclude domain="database" path="name.db" /-->
+    <exclude domain="root"/>
+    <!-- Exclude specific shared preferences that contain GCM registration Id -->
+
+    <!-- The following "include" elements are part of the auto backup -->
+    <include domain="sharedpref" path="."/>
+    <include domain="database" path="."/>
+</full-backup-content>
diff --git a/ultrasonic/src/main/res/xml/backup_rules.xml b/ultrasonic/src/main/res/xml/backup_rules.xml
new file mode 100644
index 00000000..19a1b62c
--- /dev/null
+++ b/ultrasonic/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Targeting Android 12 or higher -->
+<data-extraction-rules>
+    <cloud-backup disableIfNoEncryptionCapabilities="true">
+        <!--include domain=["file" | "database" | "sharedpref" | "external" | "root"] path="string"/-->
+        <!--exclude domain=["file" | "database" | "sharedpref" | "external" | "root"] path="string"/-->
+        <exclude domain="root"/>
+        <include domain="sharedpref" path="."/>
+        <include domain="database" path="."/>
+    </cloud-backup>
+    <device-transfer>
+        <include domain="root"/>
+        <!--exclude domain=["file" | "database" | "sharedpref" | "external" | "root"] path="string"/-->
+    </device-transfer>
+</data-extraction-rules>