ShizuStore

Bluetooth Bouncer

harvzor

1.0.0-rc3 · GitHub

Download APK
Network Android 12+ 4 months ago GPL-3.0
128 ShizuStore
551 GitHub
3 Stars
47 MB Size

More about this app

Per-device Bluetooth auto-connect control that stays paired; policy enforced via Shizuku.

Bluetooth Bouncer

Bluetooth Bouncer — Android bouncer blocking a Bluetooth device from connecting

"Sorry mate, not tonight."


Android auto-connects to every paired Bluetooth device in range. The only built-in fix is to unpair entirely.

Bluetooth Bouncer adds a missing toggle: per-device control over auto-connect. Stay paired, connect only when you want to.

Screenshots

Shizuku permission denied
How the apps looks on first open
Shizuku setup guide
Shizuku setup guide
Main device list
Main device list
Blocked device alert
Notification when a device has turned on
Temporarily connected
Notification after temporarily connecting a device

Demo video

Bluetooth Bouncer demo video
▶ Watch the demo on YouTube

Features

Feature What it does
Block / Allow Toggle auto-connection per device. Blocked devices stay paired but won't connect on their own.
Connect / Disconnect Tap Connect to immediately connect a device (temporarily allows blocked devices; allowed devices connect directly). Tap Disconnect to kick a connected device off. (Android 13+ only)
Alerts Get notified when a blocked device comes into range, so you can decide whether to let it in. (Android 13+ only)
Temporary Allow Tap the notification to let a blocked device connect just for this session. It goes back to blocked automatically when the device leaves range. Also triggered by the Connect button on a blocked device.
Survives Reboots Your blocks stick around even after restarting your phone.
Re-pair Protection If you unpair and re-pair a blocked device, the block is automatically re-applied. No surprise reconnections.
Live Status See at a glance which devices are connected, detected nearby, or were recently seen.

Requirements

  • Android 12 or higher (API 31+)
  • Shizuku — a free app that gives Bluetooth Bouncer the elevated access it needs. Android normally restricts the connection-policy API to system apps; Shizuku bridges that gap without requiring root. Bluetooth Bouncer will guide you through setup if Shizuku isn't running.

Alert and Connect/Disconnect features require Android 13+ (API 33+). The toggles and buttons simply won't appear on older versions.

Note on Disconnect for allowed devices: Disconnecting an allowed device sends a disconnect signal to its Bluetooth profiles, but Android may immediately reconnect it because the connection policy is still "allowed." If you want a persistent disconnect, use the Block toggle instead.

Tested With

This app has only been tested with the following setup — it may work on other devices and configurations, but no guarantees:

  • Phone: Xiaomi POCO X5 Pro
  • Bluetooth devices: Razer BlackShark V3 X (BT), JBL Go 4
  • Shizuku: v13.6.0

Getting Started

  1. Install Bluetooth Bouncer — download the latest APK from GitHub Releases and install it on your phone.
  2. Install Shizuku from the Play Store or GitHub.
  3. Start Shizuku — tap "Setup" in Bluetooth Bouncer and follow the instructions. You can use either Wireless Debugging (no PC needed) or ADB from a computer.
  4. Grant permission — Bluetooth Bouncer will ask for Shizuku permission the first time. Tap Allow.
  5. Block a device — you'll see all your paired Bluetooth devices. Flip the toggle next to any device to block it.

That's it. The device will stay paired but won't auto-connect anymore.

How It Works

Android has a hidden system API called setConnectionPolicy that controls whether a Bluetooth device is permitted to auto-connect. It's normally off-limits to third-party apps — only system apps can use it.

Shizuku runs a small background process with elevated shell privileges, and Bluetooth Bouncer uses it to call this API on your behalf. No root required.

Because the policy is applied at the OS level, it persists even when Bluetooth Bouncer isn't running. There's no background service draining your battery — once a device is blocked, Android itself enforces it.

Permissions

Permission Why
Bluetooth Connect Read your list of paired devices and interact with Bluetooth profiles
Notifications Alert you when a blocked device is nearby (you can decline this)
Receive Boot Completed Re-apply your blocks after restarting your phone
Companion Device Presence Detect when blocked devices come into or leave range (for the Alert feature)

Uninstalling

Because blocks are applied at the OS level (see How It Works), they persist even after Bluetooth Bouncer is uninstalled. Android does not give apps a chance to clean up before removal.

Before uninstalling, open Bluetooth Bouncer and unblock any devices you want to auto-connect again.

If you already uninstalled with devices still blocked, you can fix them from Android's Bluetooth settings — tap the blocked device to connect manually, and the policy will be reset.

Building

The only host dependency is Docker (BuildKit-capable). No Android SDK, JDK, or Gradle installation required.

docker build --output=out .

The APK is written to ./out/app-debug.apk.

To build a signed release APK locally (requires a keystore — see Releases):

RELEASE_STORE_PASSWORD=<store-password> \
RELEASE_KEY_ALIAS=release \
RELEASE_KEY_PASSWORD=<key-password> \
docker build \
  --build-arg BUILD_TYPE=release \
  --build-arg VERSION=1.0.0 \
  --secret id=keystore,src=./release.keystore \
  --secret id=store_password,env=RELEASE_STORE_PASSWORD \
  --secret id=key_alias,env=RELEASE_KEY_ALIAS \
  --secret id=key_password,env=RELEASE_KEY_PASSWORD \
  --output=out \
  .

The signed APK is written to ./out/bluetooth-bouncer-<version>.apk.

Releases

Pushing a version tag triggers an automated GitHub Actions workflow that builds a signed release APK and attaches it to the corresponding GitHub Release:

git tag v1.0.0
git push origin v1.0.0

Signing

Release APKs are signed inside the Docker build using a keystore stored as GitHub Actions secrets. The keystore is mounted as a BuildKit secret (never baked into any image layer). Four repository secrets must be configured:

Secret Description
RELEASE_KEYSTORE_BASE64 Base64-encoded keystore file
RELEASE_KEYSTORE_PASSWORD Keystore store password
RELEASE_KEY_ALIAS Key alias within the keystore
RELEASE_KEY_PASSWORD Key password

To generate a keystore and populate these secrets for the first time:

# 1. Generate the keystore
keytool -genkeypair -v \
  -keystore release.keystore \
  -alias release \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -storepass <store-password> -keypass <key-password>

# 2. Add secrets to GitHub
gh secret set RELEASE_KEYSTORE_BASE64 --body "$(base64 -w0 release.keystore)"
gh secret set RELEASE_KEYSTORE_PASSWORD --body "<store-password>"
gh secret set RELEASE_KEY_ALIAS --body "release"
gh secret set RELEASE_KEY_PASSWORD --body "<key-password>"

Keep the keystore safe. If it is lost, APKs signed with a new keystore will be treated by Android as a different app — existing users will need to uninstall and reinstall.

App Icon

The launcher icon source image is icon.png in the repo root (transparent background). To regenerate or update it:

  1. Replace icon.png with the new source image
  2. In Android Studio, right-click app/src/main/res/ → New → Image Asset
  3. Icon Type: Launcher Icons (Adaptive and Legacy)
  4. Foreground Layer: select icon.png; adjust the resize slider so the character fits within the safe zone circle
  5. Background Layer: Color → #FFFFFF (white)
  6. Click Next → Finish — this overwrites all mipmap-* directories automatically

The manifest already references @mipmap/ic_launcher and @mipmap/ic_launcher_round, so no manifest changes are needed after regenerating.

Close

How Shizuku is used

Can block and unblock paired Bluetooth devices, plus connect and disconnect them, via a `Shizuku UserService` running with privileged Bluetooth access.

This is an AI-assisted analysis of Shizuku-related usages in the app's public source code. It is best effort, so it may not catch every single usage.

How this app uses Shizuku

Bluetooth Bouncer uses Shizuku to control per-device Bluetooth auto-connect policy while keeping devices paired. All privileged work runs in a Shizuku UserService that calls hidden Bluetooth profile methods the normal app cannot reach.

  • Block devices: set a paired device to never auto-connect by applying connection policy forbidden across audio, headset and input profiles when the user toggles block in the device list.
  • Allow devices: restore normal auto-connect by applying connection policy allowed when the user unblocks a device or taps temporary allow in a notification.
  • Connect devices: actively connect a selected device across supported profiles when the user taps connect.
  • Disconnect devices: actively disconnect a selected device across supported profiles when the user taps disconnect or uses the disconnect notification action, re-applying the block for watched devices.
  • Keep blocks persistent: re-apply the forbidden policy after reboot, after a blocked device is unpaired and re-paired, and after a temporarily allowed device leaves range.

Android APIs or commands used

  • BluetoothAdapter.getProfileProxy
  • BluetoothAdapter.getRemoteDevice
  • BluetoothA2dp.setConnectionPolicy
  • BluetoothHeadset.setConnectionPolicy
  • BluetoothProfile.HID_HOST setConnectionPolicy
  • BluetoothA2dp.connect
  • BluetoothHeadset.connect
  • BluetoothProfile.HID_HOST connect
  • BluetoothA2dp.disconnect
  • BluetoothHeadset.disconnect
  • BluetoothProfile.HID_HOST disconnect
  • android.os.ServiceManager.getService
  • android.bluetooth.IBluetoothManager
  • android.app.ActivityThread.currentApplication
  • android.app.ActivityThread.getSystemContext

Notable details

Blocking keeps devices paired but prevents auto-connect. Temporary access is designed to revert automatically: leaving range or tapping disconnect restores the blocked policy. Connect, disconnect and background presence handling require Android 13 or newer.

Close

Changelog

What's new for version 1.0.0-rc3

Close

Permissions

6 permissions requested

  • android.permission.BLUETOOTH_CONNECT
  • android.permission.RECEIVE_BOOT_COMPLETED
  • android.permission.POST_NOTIFICATIONS
  • android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE
  • net.harveywilliams.bluetoothbouncer.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
  • moe.shizuku.manager.permission.API_V23
Close