1

I'd like to programatically press another application's Quick Settings Tile, e.g. from the shell or Tasker.


In this particular case, I'd like to press ProtonVPN's tile in order to automate connecting and disconnecting.

After tearing apart the app, I found that I could reliably disconnect the VPN with:

su root -c am start-foreground-service -n com.protonvpn.android/org.strongswan.android.logic.CharonVpnService -a android.net.VpnService.DISCONNECT

I can sometimes connect with:

su root -c am start-foreground-service -n com.protonvpn.android/org.strongswan.android.logic.CharonVpnService -a android.net.VpnService

However, this is not very reliable as it's an internal mechanism that bypasses much of what the app does in the process of properly establishing a Quick Connect connection.

If there's an intent that will simulate what occurs when an app's tile is pressed, it should provide a much cleaner solution.

In this instance, the app has the service com.protonvpn.android.components.QuickTileService and an intent action filter of android.service.quicksettings.action.QS_TILE however I'm at a loss for where to go from there.

1

I'm stepping out of my comfort zone with this one, but seeing as no one else has had any input, I thought I may as well mention it for you to test:

1) Go to G Play Market and install Nova Launcher.
2) Skip all the setup and go straight to Home screen with Nova as default launcher (since you're just testing functionality at this point)
3) Long press your background and select Widgets, then scroll down to Nova Launcher and find the "Activity" widget (for me it's the second widget); long-press then drag to an empty space on Home Screen
4) Once you let go to set the widget, an overlay prompt will come into focus and start loading. Depending on your device and number of apps installed, this may take a minute or two, so don't be alarmed. Once it finishes loading, scroll down to your app and locate the activity thread you're looking for and select it (you can long-press them one by one to test the function as well, it will return you back to the previous overlay prompt if the thread didn't cause a crash...if it does, you'll have to restart from step 3.

I always thought it was a neat function but never got around to testing what it was capable of doing. Hope this works out for you!

NOTE: I am enrolled in the Beta, and have the Prime (paid) version, so I'm not sure if that might affect this specific function or not. You can likely purchase for testing and request refund if necessary.

| improve this answer | |
1

In brief

Automating an already visible Quick Settings tile

# Click on a TileService of the specified component
cmd statusbar click-tile com.package.name/.service.QuickSettingsTileComponent

# You may need to expand the status bar to show the quick settings
# before it'll apply.  Not sure why.
cmd statusbar expand-settings
sleep 0.25 # 250 ms or shorter may be enough
cmd statusbar collapse

Adding a Quick Settings tile and removing it after clicking

# Expand, add tile, wait for it to initialize
cmd statusbar expand-settings
cmd statusbar add-tile com.package.name/.service.QuickSettingsTileComponent
sleep 0.1

# Click tile, wait for it to react
cmd statusbar click-tile com.package.name/.service.QuickSettingsTileComponent
sleep 0.25

# Remove tile, collapse
cmd statusbar remove-tile com.package.name/.service.QuickSettingsTileComponent
cmd statusbar collapse

Guided walkthrough

Finding package name and component

Skip this if you already know how to find the QuickSettings Tile service.

  1. Install an application like apps_Packages Info [F-Droid] to browse through the list of installed apps and all services.

  2. Find the application whose tile you want to toggle and open the application details by tapping on it

    • Example: Digital Wellbeing is com.google.android.apps.wellbeing
  3. Expand the Services dropdown in the application detail page

  4. Find the tile service, which will have the permission android.permission.BIND_QUICK_SETTINGS_TILE, then note down the component name

    • Example: Grayscale QS tile is .screen.ui.GrayscaleTileService
  5. Make note of the full package name and component name, and fill out the command below:

cmd statusbar click-tile com.package.name/.service.QuickSettingsTileComponent

Example 1: to toggle Digital Wellbeing's Grayscale QS tile…

cmd statusbar click-tile com.google.android.apps.wellbeing/.screen.ui.GrayscaleTileService

Example 2: to toggle Digital Wellbeing's Focus Mode QS tile…

cmd statusbar click-tile com.google.android.apps.wellbeing/.focusmode.quicksettings.FocusModeTileService

Automating the Quick Settings tile

Toggling the Quick Settings tile via click-tile won't apply until the Quick Settings section is expanded. As soon as the Quick Settings section is revealed, it'll work, even if the tile itself is placed on a secondary page of quick settings tiles (e.g. page 2).

This works even when the screen is locked if the QS tile doesn't require unlocking to toggle. However, the display must be on.

General steps

If the Quick Settings tile is already added…

  1. Turn on screen if it's off
  2. Expand Quick Settings via cmd statusbar expand-settings
  3. Run cmd statusbar click-tile [component] command discovered above
  4. Wait a short delay, e.g. 250 ms
  5. Optionally, close status bar via cmd statusbar collapse
  6. Optionally, turn screen off if it wasn't already on

If you don't want to keep the Quick Settings tile around…

  1. Turn on screen if it's off
  2. Expand Quick Settings via cmd statusbar expand-settings
  3. Add the Quick Settings tile via cmd statusbar add-tile [component]
  4. Wait a short delay, e.g. 100 ms
  5. Run cmd statusbar click-tile [component] command discovered above
  6. Wait a short delay, e.g. 250 ms
  7. Run cmd statusbar remove-tile [component]
  8. Optionally, close status bar via cmd statusbar collapse
  9. Optionally, turn screen off if it wasn't already on

Example shell script (with Tasker counterpart)

If the Quick Settings tile is already added…

# Wake up device
input keyevent KEYCODE_WAKEUP
#
# Tasker: Add Action -> Display -> Turn On

# Expand the Quick Settings section of the status bar
cmd statusbar expand-settings
#
# Tasker: Add Action -> Code -> Run Shell, copy above

# Click on a TileService of the specified component
cmd statusbar click-tile com.package.name/.service.QuickSettingsTileComponent
#
# Tasker: Add Action -> Code -> Run Shell, copy above, check "Use Root"

# Wait for click to register, 250 ms or shorter may be enough
sleep 0.25
#
# Tasker: Add Action -> Task -> Wait, then set delay to 250 ms

# Optional: collapse status bar
# This won't work when on the lockscreen, but turning the screen off
# also collapses the status bar for you.
cmd statusbar collapse
#
# Tasker: Add Action -> Code -> Run Shell, copy above

# Optional: put device to sleep
# (Up to you: only turn off if the screen wasn't already on.)
input keyevent KEYCODE_POWER
#
# Tasker: Add Action -> Display -> Turn Off, enabling "Lock"

If you don't want to keep the Quick Settings tile around…

# Wake up device
input keyevent KEYCODE_WAKEUP
#
# Tasker: Add Action -> Display -> Turn On

# Expand the Quick Settings section of the status bar
cmd statusbar expand-settings
#
# Tasker: Add Action -> Code -> Run Shell, copy above

# Add the TileService of the specified component, click on it, then
# remove it
# 'sleep' gives time for the tile to initialize and the click to
# register, 100 ms or shorter may be enough
cmd statusbar add-tile com.package.name/.service.QuickSettingsTileComponent
sleep 0.1
cmd statusbar click-tile com.package.name/.service.QuickSettingsTileComponent
sleep 0.25
cmd statusbar remove-tile com.package.name/.service.QuickSettingsTileComponent
#
# Tasker: Add Action -> Code -> Run Shell, copy above, check "Use Root"

# No need to wait for click to register, waiting was done above

# Optional: collapse status bar
# This won't work when on the lockscreen, but turning the screen off
# also collapses the status bar for you.
cmd statusbar collapse
#
# Tasker: Add Action -> Code -> Run Shell, copy above

# Optional: put device to sleep
# (Up to you: only turn off if the screen wasn't already on.)
input keyevent KEYCODE_POWER
#
# Tasker: Add Action -> Display -> Turn Off, enabling "Lock"

NOTE: root or ADB is required!

If you are using an automation app rather than adb shell, cmd statusbar add-tile/click-tile/remove-tile must be run with root or via e.g. ADB WiFi actions.

The other cmd statusbar commands may be run without root.

Tasker/etc have non-root options for waking the screen and putting it to sleep.

Other details

cmd statusbar click-tile appears to have been added with Android 7.0, so this should work ever since custom quick setting tiles were officially added to Android.

I've not found any way to read the Quick Settings tile state, e.g. active/on or inactive/off. To work around this, I've checked logcat and app notifications via dumpsys notification to see what's running or paused.

I've also not found out how to toggle the built-in Android System Quick Settings tiles; fortunately, most of them appear to be achievable via other means (secure settings, service calls, etc).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.