diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 9633e2b2bd..ba9826cfee 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -57,6 +57,9 @@
+
{
+ TSLog.d(TAG, "Shortcut: Connect VPN triggered")
+ App.get().startVPN()
+ finish()
+ true
+ }
+ action == ACTION_SHORTCUT_DISCONNECT || shortcutAction == "disconnect" -> {
+ TSLog.d(TAG, "Shortcut: Disconnect VPN triggered")
+ App.get().stopVPN()
+ finish()
+ true
+ }
+ else -> false
+ }
+ }
+
private fun login(urlString: String) {
// Launch coroutine to listen for state changes. When the user completes login, relaunch
// MainActivity to bring the app back to focus.
diff --git a/android/src/main/res/drawable/ic_shortcut_connect.xml b/android/src/main/res/drawable/ic_shortcut_connect.xml
new file mode 100644
index 0000000000..23e8b183c4
--- /dev/null
+++ b/android/src/main/res/drawable/ic_shortcut_connect.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/android/src/main/res/drawable/ic_shortcut_disconnect.xml b/android/src/main/res/drawable/ic_shortcut_disconnect.xml
new file mode 100644
index 0000000000..71015e64ac
--- /dev/null
+++ b/android/src/main/res/drawable/ic_shortcut_disconnect.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml
index 608f1f2a2e..aabe0a0a8c 100644
--- a/android/src/main/res/values/strings.xml
+++ b/android/src/main/res/values/strings.xml
@@ -7,6 +7,9 @@
None
Connect
Disconnect
+ Connect to Tailscale
+ Disconnect from Tailscale
+ Tailscale shortcut is not available
Unknown user
Connected
Using exit node (%s)
diff --git a/android/src/main/res/xml/shortcuts.xml b/android/src/main/res/xml/shortcuts.xml
new file mode 100644
index 0000000000..1cd710cbb3
--- /dev/null
+++ b/android/src/main/res/xml/shortcuts.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+